Wenn Sie Java-/Kotlin-Zuweisungen aufzeichnen, können Sie unerwünschte Speichermuster erkennen, die möglicherweise Leistungsprobleme verursachen. Der Profiler kann Ihnen Folgendes zu Objektzuweisungen anzeigen:
- Welche Arten von Objekten wurden zugewiesen und wie viel Speicherplatz belegen sie?
- Der Stacktrace jeder Zuweisung, einschließlich des Threads, in dem sie erfolgt ist.
- Wann die Objekte freigegeben wurden.
Sie sollten Speicherzuweisungen bei normaler und extremer Nutzerinteraktion aufzeichnen, um genau zu ermitteln, wo in Ihrem Code entweder zu viele Objekte in kurzer Zeit zugewiesen werden oder Objekte zugewiesen werden, die verloren gehen. Weitere Informationen
Java-/Kotlin-Zuweisungen aufzeichnen
Wenn Sie Java-/Kotlin-Zuweisungen aufzeichnen möchten, wählen Sie auf dem Tab Startseite des Profilers die Aufgabe Speicherverbrauch erfassen (Java-/Kotlin-Zuweisungen) aus. Hinweis: Sie benötigen eine debugfähige App (verwenden Sie Profiler: run 'app' as debuggable (complete data)), um Java-/Kotlin-Zuweisungen aufzuzeichnen.
In Android Studio werden standardmäßig alle Objektzuweisungen im Arbeitsspeicher erfasst. Wenn Ihre App viele Objekte zuweist, kann es während des Profilings zu sichtbaren Verlangsamungen kommen. Wenn Sie die Leistung beim Profiling verbessern möchten, wählen Sie im Drop-down-Menü Allocation Tracking (Zuweisungs-Tracking) die Option Sampled (Stichprobe) anstelle von Full (Vollständig) aus. Beim Sampling erfasst der Profiler in regelmäßigen Abständen Objektzuweisungen im Arbeitsspeicher.
Wenn Sie während der Aufzeichnung eine Garbage Collection erzwingen möchten, klicken Sie auf das Mülleimersymbol .
Übersicht über Java-/Kotlin-Zuweisungen
Nachdem Sie die Aufnahme beendet haben, wird Folgendes angezeigt:
- Die Ereigniszeitachse zeigt Aktivitätsstatus, Nutzereingabeereignisse und Bildschirmdrehungsereignisse.
- In der Zeitachse zur Speichernutzung werden die folgenden Informationen angezeigt. Wählen Sie einen Teil der Zeitachse aus, um nach einem bestimmten Zeitraum zu filtern.
- Ein gestapeltes Diagramm, das zeigt, wie viel Speicher von jeder Speicherkategorie verwendet wird. Die y-Achse befindet sich links und die Farblegende oben.
- Eine gestrichelte Linie gibt die Anzahl der zugewiesenen Objekte an, wie auf der Y-Achse rechts dargestellt.
- Ein Symbol für jedes Ereignis der automatischen Speicherbereinigung.
- Auf dem Tab Tabelle wird eine Liste der Klassen angezeigt. Gesamtzahl ist die Anzahl der Zuweisungen am Ende des ausgewählten Zeitbereichs (Zuweisungen minus Freigaben). Daher ist es möglicherweise sinnvoll, zuerst Klassen mit den höchsten Gesamtzahl-Werten zu debuggen. Wenn Sie sich mehr für die Fehlerbehebung bei Kursen auf Grundlage der Spitzenzuweisungen im ausgewählten Zeitraum interessieren, sortieren Sie nach Zuweisungen. Die Remaining Size (verbleibende Größe) ist die Allocations Size (Größe der Zuweisungen) minus die Deallocations Size (Größe der Freigaben) in Byte.
- Wenn Sie in der Liste Tabelle auf eine Klasse klicken, wird der Bereich Instanz mit einer Liste der zugehörigen Objekte geöffnet. Diese enthält Informationen dazu, wann die Objekte zugewiesen und wann sie freigegeben wurden, sowie ihre flache Größe.
Auf dem Tab Visualisierung sehen Sie eine aggregierte Ansicht aller Objekte im Aufrufstack für den ausgewählten Zeitraum. Sie zeigt im Wesentlichen, wie viel Gesamtspeicher der Aufrufstapel mit den angezeigten Instanzen belegt. In der ersten Zeile wird der Threadname angezeigt. Standardmäßig werden die Objekte basierend auf der Zuweisungsgröße von links nach rechts gestapelt. Verwenden Sie das Drop-down-Menü, um die Reihenfolge zu ändern.
Mit dem Drop-down-Menü „Heap“ können Sie nach bestimmten Heaps filtern. Zusätzlich zu den Filtern, die beim Erfassen eines Heap-Dumps verfügbar sind, können Sie nach Klassen im JNI-Heap filtern. Dieser Heap zeigt, wo JNI-Referenzen (Java Native Interface) zugewiesen und freigegeben werden.
Wählen Sie im Drop-down-Menü „Anordnung“ aus, wie die Zuweisungen angeordnet werden sollen. Zusätzlich zu den Optionen, die beim Erfassen eines Heap-Dumps verfügbar sind, können Sie auch nach Callstack sortieren.
So wird der Arbeitsspeicher gezählt
Die Zahlen oben auf der Seite basieren auf allen privaten Speicherseiten, die Ihre App laut Android-System zugewiesen hat. Seiten, die mit dem System oder anderen Apps geteilt wurden, sind in dieser Anzahl nicht enthalten. Die Kategorien in der Speicherzählung sind:
- Java: Speicher von Objekten, die aus Java- oder Kotlin-Code zugewiesen wurden.
Nativ: Arbeitsspeicher von Objekten, die aus C- oder C++-Code zugewiesen wurden.
Auch wenn Sie in Ihrer App kein C++ verwenden, wird hier möglicherweise nativer Speicher belegt, da das Android-Framework nativen Speicher verwendet, um verschiedene Aufgaben für Sie zu erledigen, z. B. beim Verarbeiten von Bild-Assets und anderen Grafiken – auch wenn der von Ihnen geschriebene Code in Java oder Kotlin ist.
Grafik: Arbeitsspeicher, der für Grafikpufferwarteschlangen verwendet wird, um Pixel auf dem Bildschirm darzustellen, einschließlich GL-Oberflächen, GL-Texturen usw. Dabei handelt es sich um Arbeitsspeicher, der mit der CPU geteilt wird, nicht um dedizierten GPU-Arbeitsspeicher.
Stack: Speicher, der sowohl von nativen als auch von Java-Stacks in Ihrer App verwendet wird. Dies hängt in der Regel davon ab, wie viele Threads in Ihrer App ausgeführt werden.
Code: Speicher, den Ihre App für Code und Ressourcen verwendet, z. B. DEX-Bytecode, optimierter oder kompilierter DEX-Code.
so
-Bibliotheken und Schriftarten.Andere: Arbeitsspeicher, der von Ihrer App verwendet wird und den das System nicht kategorisieren kann.
Zugewiesen: Die Anzahl der Java-/Kotlin-Objekte, die von Ihrer App zugewiesen wurden. Objekte, die in C oder C++ zugewiesen wurden, werden hier nicht berücksichtigt.
Zuweisungsdatensatz prüfen
So prüfen Sie den Zuweisungsdatensatz:
- Sehen Sie sich die Klassenliste auf dem Tab Tabelle an, um Objekte mit ungewöhnlich großen Werten für Zuweisungen oder Gesamtzahl (je nachdem, was Sie optimieren) zu finden, die möglicherweise verloren gegangen sind.
- Klicken Sie im Bereich Instanzansicht auf eine Instanz. Je nachdem, was für diese Instanz zutrifft, wird der Tab Felder oder Zuweisungs-Callstack geöffnet. Anhand der Informationen auf den Tabs Felder oder Zuweisungs-Callstack können Sie feststellen, ob Instanzen wirklich benötigt werden oder unnötige Duplikate sind.
Klicken Sie mit der rechten Maustaste auf einen beliebigen Listeneintrag, um zum entsprechenden Quellcode zu springen.
Globale JNI-Referenzen ansehen
Java Native Interface (JNI) ist ein Framework, mit dem Java-Code und nativer Code sich gegenseitig aufrufen können. JNI-Referenzen werden manuell vom nativen Code verwaltet. Daher können Probleme wie die folgenden auftreten:
- Von nativem Code verwendete Java-Objekte werden zu lange aktiv gehalten.
- Einige Objekte im Java-Heap sind möglicherweise nicht mehr erreichbar, wenn eine JNI-Referenz verworfen wird, ohne dass sie zuvor explizit gelöscht wurde.
- Das globale JNI-Referenzlimit ist ausgeschöpft.
Um solche Probleme zu beheben, wählen Sie im Profiler JNI-Heap ansehen aus, um alle globalen JNI-Referenzen aufzurufen und nach Java-Typen und nativen Callstacks zu filtern. Klicken Sie mit der rechten Maustaste auf ein Instanzfeld auf dem Tab Felder und wählen Sie Zur Instanz aus, um den entsprechenden Zuweisungs-Callstack aufzurufen.
Auf dem Tab Allocation Call Stack (Aufrufstack für Zuweisung) sehen Sie, wo die JNI-Referenzen in Ihrem Code zugewiesen und freigegeben werden.
Weitere Informationen zu JNI finden Sie unter JNI-Tipps.