Riesiges Byte [] in meiner App nach HPROF

8

Von Zeit zu Zeit, insbesondere bei der Implementierung neuer Funktionen in meiner App, verwende ich DDMS + HPROF, um die Speicher- und Heap-Nutzung zu analysieren. Da die App keine Performance-ANR-Probleme zu haben scheint und alles reibungslos funktioniert, habe ich mich zunächst nicht darum gekümmert - aber jetzt, wie ich sehe, ist es ungefähr immer gleich groß, ich frage mich, was zum Teufel das kann sei.

Jedes Mal, wenn ich einen HPROF starte, überprüfe ich die Registerkarte Leckverdächtige . Es gibt immer eine android.graphics.Bitmap -Instanz, die etwa 25% des gesamten verwendeten Heapspeichers beansprucht.

Ich wollte etwas weiter wissen, worum es geht, also habe ich den -Dominatorbaum geöffnet und folgendes gesehen:

Es gibt also eine riesige byte[] -Instanz, die eine Menge Heap speichert und nie wird freigegeben. Laut diesem habe ich den Wert dieses byte[] kopiert, ihn in eine .data -Datei kopiert, mit Gimp geöffnet und Da ist das Ergebnis:

Es sieht im Grunde so aus wie der "alpha (0)" Teil eines PNG-Bildes. Unter Berücksichtigung der folgenden Fakten:

  • Alle meine Bilddateien sind & lt; 8K groß
  • Nur einige von ihnen sind PNG - die verbleibenden, die ich in JPG konvertieren konnte, tat ich
  • Egal, ob ich weitere Bilder hinzufüge, die Größe dieses byte[] war seit dem Start der App (vor 4 Monaten) immer ungefähr gleich.
  • Um es zu debuggen, habe ich versucht, die beliebige Image-Datei aus den Ordnern drawable und drawable-xxx zu entfernen und die App ohne aufrufbare Ressourcen auszuführen, und die byte[] war immer noch da
  • Ich habe fast alle Layouts entfernt und nur die Grundfunktionalität und das gleiche Ergebnis
  • gelassen
  • In der Dominator-Struktur ist die Stammklasse android.graphics.Bitmap

Weiß jemand, was es byte[] und wenn ich etwas tun sollte, um es zu befreien?

Jede Hilfe geschätzt!

    
nKn 22.01.2014, 18:40
quelle

1 Antwort

6

Nur um ein paar Dinge zu verdeutlichen:

  • Bilder / Zeichen in Ihrer App werden im Speicher in Form von android.graphics.Bitmap verwendet.
  • Ab Android 3.0 (API-Ebene 11) werden die Pixeldaten zusammen mit der zugehörigen Bitmap auf dem Dalvik-Heap gespeichert. ( Bitmap-Speicher verwalten )
  • "riesiges Byte []" ist wahrscheinlich eine Übertreibung, da es etwas mehr als 1MB Heap-Speicherplatz ist.

Der Leckverdächtige Bericht kann hilfreich sein, aber in diesem Fall sagt er Ihnen nicht viel aus, wenn man bedenkt, dass sein größter Verdächtiger knapp über 1 MB Speicher ist. Moderne Geräte bieten 64MB + Heaps.

Lassen Sie uns die Speicheranforderungen für diese Bitmap berechnen. Diese Bitmap belegt 1.127.584 Byte auf dem Heap. Wenn wir davon ausgehen, dass diese Bitmap mit ARGB_8888 konfiguriert ist, verwendet jedes Pixel 4 Byte, was bedeutet, dass Ihr Bild 281.896 Pixel (oder etwa 530x530 Pixel) enthält. Klingt das unvernünftig für das, was Sie tun?

Beachten Sie auch, wie Android für die verschiedenen "Buckets" für Zeichenobjekte skaliert: mdpi, hdpi, xhdpi usw. Nehmen wir an, Sie haben ein 200x200-Bild im mdpi Bucket, und Sie öffnen das App auf einem xhdpi Gerät. Dieses Bild wird doppelt so groß skaliert und hat eine Auflösung von 400x400 im Gerät. Während also das 200x200-Bild nicht viel Heap-Speicher benötigt (200 x 200 x 4 = 160 kb ), benötigt das 400x400-Image eine relativ größere Menge (4x) Heap-Speicher (400 x 400 x 4) = 640 KB ). Weitere Informationen hierzu finden Sie unter Unterstützung mehrerer Bildschirme .

Ein nettes Werkzeug, um schnell Unterschiede zu den Bildbereichen zu berechnen: Android DPI Calculator

Sie sagten, Sie hätten einige Ihrer Zeichen entfernt, aber was bleibt übrig? Haben Sie bereits Zeichen berücksichtigt, die möglicherweise von externen Bibliotheken stammen?

Um Ihre letzte Frage zu beantworten: Weiß jemand, was es dieses Byte [] und ob ich etwas tun sollte, um es freizugeben?

Ich würde sagen: Diese kleine Menge an Speicher auf Ihrem Haufen ist nichts, worüber Sie sich Sorgen machen müssen. Wenn es dich stört, behalte es im Auge und stelle sicher, dass es nicht über das hinausgeht, was praktisch erscheint. Wenn Sie immer noch einen Speicherverlust vermuten, navigieren Sie zwischen den Bildschirmen und beobachten Sie, ob der Heap weiter wächst. Vorausgesetzt, dass Sie keine Bitmaps zwischenspeichern, sollte der Heap eine konsistente / vorhersehbare Größe beibehalten, wenn Sie zwischen zwei Bildschirmen hin und her navigieren

Als eine Nebenbemerkung macht es DDMS sehr einfach, die Heap-Größe im laufenden Betrieb zu überwachen. HPROF-Dumps sind nicht erforderlich, bis Sie zum Eintauchen bereit sind. Sehen Sie sich DDMS verwenden . Achten Sie besonders auf die Schaltfläche "Ursache-GC", da diese benötigt wird, um die Aktualisierung der ursprünglichen Heap-Größe auszulösen.

- UPDATE -

Um dies weiter zu beantworten, besteht ein nicht unterstützter Verdacht darin, dass einige der Assets der App (System-Assets / Texturen?) in den Speicherplatz Ihrer App geladen werden. Sehen Sie sich Folie 64 hier an: Was ist neu in Android 4.4 .

  

Android 4.4 generiert jetzt eine einzelne Textur, die alle Framework-Assets enthält, die von allen Prozessen gemeinsam genutzt werden. Dies spart in jedem Prozess ein wenig Speicher, unterstützt aber auch das Batching und Zusammenführen von Zeichenvorgängen, um Anwendungen automatisch zu optimieren.

Dies scheint zu implizieren, dass Speicher für System-Bitmaps / -Zeichnungen in jeder App verwendet wird, die eine Version vor 4.4 ausführt. Wenn dies der Fall ist, würde ich fragen, ob diese 1MB dieser Speicherplatz ist. Ich frage mich, ob Sie Ihre App auf einem 4.4 Gerät / Emulator ausführen und sehen können, ob der gleiche Speicher verwendet wird.

Haben Sie als weiteren Test versucht, die Speicherbelegung in einer Barebones-App zu überprüfen (alle entfernten Zeichnungsdateien usw.)?

    
Tanner Perrien 29.01.2014, 08:40
quelle