ich ein Android-Dienst haben, die eine Benachrichtigung aktualisiert jede Sekunde dieses Thema mit (Kommentare sind nicht wirklich relevant):Android und Java: Speichernutzung auf einer Serviceschleife reduzieren
thread = new Thread() {
@Override
public void run() {
// Preparando la notificación de Swap
NotificationCompat.Builder notificationSwap =
new NotificationCompat.Builder(context)
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setContentTitle("Notificator:");
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int notificationSwapId = 1; // TODO: Asignar un ID que no sea "Magic number"
while (!stop) {
String swapInfo = null;
try{ // TODO: free devuelve siempre 4 líneas?
Process free = Runtime.getRuntime().exec("free");
BufferedReader freeOut =
new BufferedReader(
new InputStreamReader(new DataInputStream(free.getInputStream())));
free.waitFor();
freeOut.readLine();
freeOut.readLine();
freeOut.readLine();
swapInfo = freeOut.readLine();
}catch(Exception e){
Log.e("ERROR", e.toString()); // TODO: Mejorar esto
}
Scanner scanner = new Scanner(swapInfo); // TODO: Mejorar esto
String swapInfo2 = null;
if (scanner.hasNext()) {
scanner.skip("Swap:");
}
if (scanner.hasNextInt()) {
/*swapInfo2 = "Total: " + */scanner.nextInt();
}
if (scanner.hasNextInt()) {
swapInfo2 = "Usado: " + scanner.nextInt();
}
if (scanner.hasNextInt()) {
swapInfo2 += "\nLibre: " + scanner.nextInt();
}
// Notificando
notificationSwap.setContentText(swapInfo2);
notificationManager.notify(notificationSwapId, notificationSwap.build());
// Intentando liberar memoria
//System.gc();
try {
Thread.sleep(new Integer(PreferenceManager.getDefaultSharedPreferences(context).getString("frecuency", "60000"))); // TODO: Mejorar esto
} catch (InterruptedException e){
Log.d("Notificator (Service)", "Deteniendo el hilo durante la espera"); // TODO: Mejorar esto
// TODO: ¿Qué pasa si el hilo es interrumpido fuera del try/catch? Si pilla la interrupción no hace falta la variable stop
}
}
}
};
Das Problem ist, dass es über verwendet 20 MB Speicher, aber wenn ich die "//System.gc();" Linie diese Zahl sinkt auf ca. 3/4MB, das ist eine Menge Müll. Aber wenn ich den gesamten Garbage Collector in jeder Schleife abspiele, scheint das für mich nicht sehr effizient zu sein und die CPU-Auslastung steigt.
Das ist der Grund, warum ich Müllsammler nicht mag, in einer C++ Schleife nur mit Hilfe von Autovariablen hätte ich dieses Problem nicht, aber ich denke, das könnte besser gemacht werden, da ich weder wirklich zu Java noch Android.
Meine Hauptfrage ist also, wie kann ich den Speicherverbrauch auf eine effizientere Weise senken? Ich würde mir auch bessere Möglichkeiten vorstellen, um eine Benachrichtigung auf Android zu verbessern, aber was ich wirklich brauche, ist zu verhindern, dass diese Art von Code so viel Speicher verbraucht.
UPDATE:
Antworten sind darauf hindeutet, dass ich den Strom schließen sollte, die Scanner, etc., ich bin nicht wirklich sicher, ob dies necesary ist oder nicht (Schließen des Stroms und der Scanner löst nicht die Problem), aber ich denke, das ist nicht das Problem, da sie sowieso erfolgreich gelöscht werden.
Das Problem ist, dass sie häufen sich vor dem Löschen und ich möchte sie löschen, bevor der Thread schläft statt auf den Garbage Collector zu warten, und da das nicht in Java getan werden kann, soweit ich weiß, brauche ich eine mehr "Garbage Collector Friendly" -Approach.
Sie können auch die Zeile 'scanner.close()' hinter 'freeOut.close()' einfügen. Hauptproblem hier ist, dass Sie einen neuen BufferedReader und einen neuen Scanner für jeden Lauf in der While-Schleife erstellen und Sie nie schließen, daher die große Speicherauslastung. –
Danke, aber die Objekte werden gelöscht, so dass das nicht das Problem ist. – JotaGe