3 Stimmen

Verwendung von SAX-Parser in Android - OutOfMemory-Problem

Ich habe mit einem SAX-Parser für eine Weile jetzt, um Daten aus verschiedenen XML zu erhalten, aber heute bin ich hämmern meinen Kopf auf ein neues Problem mit einem hudge XML (im Vergleich zu den vorherigen . hier rund 12k Zeilen) mit vielen sich wiederholenden Elemente in es. Die meiste Zeit, die Elemente sind Teil eines Blocks :

  <content>

  <item lbl="blabla">
    <item lbl="blabla"/>
    <item lbl="blabla"/>
  </item>

  <item lbl="blabla">
    <item lbl="blabla"/>
    <item lbl="blabla"/>
    <item lbl="blabla"/>
    <item lbl="blabla"/>
    <item lbl="blabla"/>
    <item lbl="blabla"/>
  </item>
</content>

Der Blabla-Teil ändert sich natürlich... Aber ich möchte die Struktur der Artikel beibehalten (es sind Titel und Untertitel). Dazu füge ich jedem blabla einen Anfangs- und Endtag hinzu <itemx>blabla</itemx> , wobei x die Position im Baum der Elemente (1, 2, 3 oder 4) ist. Der etwas problematische Teil ist, dass mit, dass ich Tausende von nutzlosen Objekten erstellen und der Garbage Collector hat keine Zeit, nach dem Parser zu reinigen, und die unvermeidliche OutOfMemory kommt in mein Gesicht... Ich habe keine Idee, wie man damit umgehen kann; Die beste Technik wäre, wenn ich den gesamten Inhalt von <content></content> aber ich bin mir nicht sicher, ob dies mit einem SAX-Parser möglich ist.

Jede Hilfe ist willkommen und jede Lösung wird dankbar angenommen...

3voto

Ben S Punkte 66945

Wenn die Daten, die Sie zu lesen versuchen, den verfügbaren Speicherplatz überschreiten, dann müssen Sie die Daten zu persistieren, um Speicherplatz freizugeben um weiterzulesen.

Haben Sie schon einmal daran gedacht, Ihre Daten in einem Sqlite-Datenbank wie Sie es einlesen?

Sie sollten es auch vermeiden, tonnenweise nutzlose temporäre Objekte zu erstellen, denn Sie könnten mit Mutation eines einzelnen Objekts oder einer kleinen Gruppe von Objekten um Müllansammlungen zu vermeiden?

Wenn Sie den gesamten Dokumentbaum im Speicher haben wollen, sollten Sie einen DOM-Parser ( DocumentBuilder ist dafür auf Android verfügbar). Wenn Ihnen jedoch bei der Verwendung des SAX-Parsers der Speicher ausgeht, ist es sehr wahrscheinlich, dass auch dem DOM-Parser der Speicher ausgeht, es sei denn, Ihre SAX-Ereignisse erzeugen und zerstören Unmengen von Objektinstanzen.

2voto

hackbod Punkte 89543

In den meisten Fällen können Sie keine Objekte so schnell erstellen, dass die GC nicht mithalten kann. In der Tat, wenn eine GC passieren muss, wird Ihre gesamte Anwendung angehalten, bis sie abgeschlossen ist, so dass Sie einfach nicht vor ihr kommen können.

Die einzige Ausnahme sind Bitmaps, die ein wenig speziell gehandhabt werden - sie zählen gegen den Java-Heap, obwohl ihre Zuweisungen nicht auf ihm geschehen. Das ist in Ordnung, außer dass der Speicher einer Bitmap nicht freigegeben wird, bis ihr Finalizer läuft, und Finalizer tun laufen getrennt von der Müllabfuhr und blockieren eine Anwendung nicht. Wenn Sie also eine Reihe von Bitmaps erstellen und sie einfach loslassen (ohne die Methode zur expliziten Freigabe des Bitmap-Speichers aufzurufen), kann dies tatsächlich zu einer "Out of Memory"-Ausnahme führen.

Aber wenn Sie nicht zuweisen (und loslassen) Bitmap-Objekte, haben Sie ein anderes Problem, wahrscheinlich nur... nicht genug Speicher für alle Ihre Zuweisungen. Sie können das Hat-Tool (und in geringerem Maße die einfachen Java-Heap-Informationen in DDMS) verwenden, um zu sehen, was Sie zugewiesen haben, das so viel Speicherplatz verbraucht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X