2013-06-22 4 views
5

Ich bekam OutOfMemoryError Nachrichten in LogCat und meine App stürzte ab, weil die Fehler nicht abgefangen wurden.

Zwei Dinge verursachten die OutOfMemoryError:
1. Lesen einer großen Textdatei in eine Zeichenfolge.
2. Senden dieser Zeichenfolge an meine TextView.

Das einfache Hinzufügen eines Catch zu diesen beiden Dingen fängt nicht nur den OutOfMemoryError ab, sondern scheint auch das Problem des fehlenden Arbeitsspeichers vollständig zu lösen.
Kein Absturz mehr und keine weiteren Fehlermeldungen in LogCat. Die App läuft einfach perfekt.

Wie ist das möglich? Was genau passiert?


'Catching' OutOfMemoryError löst das Problem der Speicherauslastung vollständig?

Mit diesem Code, war ich immer die Fehlermeldungen & App abstürzt:

try 
{ 
myString = new Scanner(new File(myFilePath)).useDelimiter("\\A").next(); 
} 
catch (FileNotFoundException e) 
{ 
e.printStackTrace(); 
} 


myTextView.setText(myString); 



Nur durch 'Fang' den OutOfMemoryError, keine Fehlermeldungen mehr in LogCat und kein Krachen:

try 
{ 
myString = new Scanner(new File(myFilePath)).useDelimiter("\\A").next(); 
} 
catch (FileNotFoundException e) 
{ 
e.printStackTrace(); 
} 
catch(OutOfMemoryError e) 
{ 
} 


try 
{ 
myTextView.setText(myString); 
} 
catch(OutOfMemoryError e) 
{ 
} 
+2

sehen Protokolle e.printstacktrace in OutOfMemoryError catch-Block – Calvin

+1

mit @Droider Zustimmen hinzuzufügen. Sie sehen keine Fehlermeldungen, weil Sie sie nicht wie zuvor ausdrucken. – csmckelvey

+0

Siehe http://stackoverflow.com/questions/2679330/catching-java-lang-outofmemoryerror – Raedwald

Antwort

1

Wenn Sie die OutOfMemoryError fangen, der Garbage Collector versucht, den Speicher freizugeben bisher verwendeten und damit die Anwendung weitermachen kann, wenn die Anwendung das lassen Müllsammler macht seine Arbeit (d. h Die Anwendung hat keinen Verweis mehr auf diese große Zeichenfolge.

Allerdings ist das Abfangen eines OutOfMemoryError bei weitem nicht fehlerfrei. Siehe Catching java.lang.OutOfMemoryError?.

2

Ich denke, Ihre Zeichenfolge ist nicht vollständig geladen, oder auch wenn es ist (es kann den Fehler nur nach dem Hinzufügen des Textes werfen), was passiert, hängt von der aktuellen Speicher für Ihre App so abfangen OutOfMemoryError ist kein praktikable Lösung hier.

Wenn Sie wirklich eine große Zeichenkette laden und in einem EditText anzeigen möchten, empfehle ich Ihnen, nur einen kleinen Teil der Datei (sagen wir 50kB) zu laden, und implementieren Sie eine Art von Paging, wie eine Schaltfläche lädt die nächsten 50kB. Sie können auch zusätzliche Zeilen laden, wenn der Benutzer durch die EditText scrollt.

1

Wenn Sie die Ausnahme abfangen, versucht die JVM, sie wiederherzustellen, indem sie den Garbage Collector aufruft und die nicht mehr verwendeten Objekte abschabt.

Dies könnte das Problem in Ihrem Fall lösen. Aber stellen Sie sich vor, dass das Problem wegen schlechter Codierung und Speicherlecks in Ihrem gesamten Code auftritt. Catching löst das Problem nicht, da GC keine Objekte sammelt. GC wird häufiger eingesetzt und die Leistung Ihrer Anwendung wird sinken, bis sie unbrauchbar wird.

Dieser Fehler tritt grundsätzlich auf, wenn die JVM nicht mehr Speicher auf Heap für neue Objekte zuweisen kann.Das Abfangen der Ausnahme und das Bereinigen und Freigeben von Speicher durch den GC kann eine Lösung sein, aber Sie sind sich nie sicher, ob Sie sich im wiederherstellbaren Zustand befinden. Ich würde den catch-Block verwenden, um den Fehler zu beheben, ihn zu protokollieren und die Anwendung zu schließen. Wenn Sie das Speicherproblem in diesem Fall lösen wollen, tun es richtig und die JVM mit mehr Speicher initialisieren (das Java-Argument -Xmx)

+0

Ich habe die Ausnahme in einer Bild-Reflektionsmethode. Kann ich den Fehler abfangen, wenn das passiert, die Verarbeitung stoppen, die Objekte bereinigen und einfach das Originalbild verwenden? – frostymarvelous

+0

Es ist wirklich eine schlechte Übung, eine solche Ausnahme zu bekommen. Eine bessere Vorgehensweise wäre es, diese Ausnahme zu vermeiden, indem 1) versucht wird, zu finden, wo der Code leckt, 2) der Speicher erhöht wird, der der JVM beim Start des Programms gegeben wird (mit -Xmx). Außerdem bin ich nicht sicher, was meinst du mit "image reflection method", kannst du das ein bisschen erklären? – darijan

+0

Grundsätzlich erstelle ich ein neues Bild von einem bestehenden, das das Bild widerspiegelt. Tut mir leid, ich schätze, das kommt als Reflection vor. Wie auch immer, der Code ist nicht undicht. Ich bekomme den Fehler manchmal beim Erstellen eines neuen Bildes mit Bitmap.createBitmap. Wenn alles fehlschlägt, muss ich Subsampling verwenden, denke ich, aber die Bilder sind bereits klein genug. – frostymarvelous

Verwandte Themen