Beispiele für Leistungsmessung und -analyse

Diese Beispiele zeigen, wie das System-Tracing mit MacroBenchmark zusammen mit dem Speicherprofiling verwendet wird, um bestimmte Arten von Leistungsproblemen zu messen und zu verbessern.

Fehler beim Start der Anwendung mit systrace beheben

Beim Debugging der Startzeit empfehlen wir die Verwendung von Systrace-Logs. Systrace ist ein System, das mithilfe von vorinstrumentiertem Code ausgibt, wie lange bestimmte Ereignisse dauern, wenn sie eintreten. Mit diesen Traces können Sie sehen, was in Ihrer Anwendung oder sogar in anderen Prozessen im gesamten System passiert. Die Android-Plattform und die Jetpack-Bibliotheken sind für viele wichtige Ereignisse in einer Anwendung instrumentiert. Diese werden entsprechend protokolliert. Sie können Ihre Anwendungen auch mit eigenen benutzerdefinierten Traces instrumentieren, die in denselben Systrace-Visualisierungstools angezeigt werden, um ein Gesamtbild dessen zu erhalten, was in der Anwendung passiert ist.

Systrace oder Perfetto verwenden

Weitere Informationen zur grundlegenden Systrace-Nutzung finden Sie im folgenden Video: Debugging der Anwendungsleistung.

Um die Startzeit zu analysieren, müssen Sie zuerst verstehen, was während des Starts passiert. Falls Sie weitere Informationen als auf dieser Seite benötigen, bietet die Dokumentation zur Startzeit von Anwendungen einen Überblick über den Startvorgang von Anwendungen.

Die Phasen des App-Starts sind:

  • Prozess starten
  • Generische Anwendungsobjekte initialisieren
  • Aktivität erstellen und initialisieren
  • Layout aufblähen
  • Ersten Frame zeichnen

Starttypen haben die folgenden Phasen:

  • Kaltstart: Dies tritt auf, wenn die Anwendung zum ersten Mal seit dem Start gestartet oder der Anwendungsprozess vom Nutzer oder vom System beendet wurde. Beim Start wird ein neuer Prozess ohne gespeicherten Status erstellt.
  • Warmstart: Dieser Fall tritt auf, wenn die Anwendung bereits im Hintergrund ausgeführt wird, die Aktivität jedoch neu erstellt und in den Vordergrund gebracht werden muss. Die Aktivität wird entweder während der Wiederverwendung des vorhandenen Prozesses neu erstellt oder der Prozess wird mit dem Status „Gespeicherte Elemente“ neu erstellt. Die MacroBenchmark-Testbibliothek unterstützt konsistente Warmstarttests mit der ersten Option.
  • Heißstart: Dies tritt auf, wenn der Prozess und die Aktivität noch ausgeführt werden und nur in den Vordergrund gebracht werden müssen. Dabei werden bei Bedarf Objekte neu erstellt und die neue Vordergrundaktivität gerendert. Dies ist das kürzeste Szenario für Start-ups.

Wir empfehlen, Systraces mit der App für das System-Tracing auf dem Gerät zu erfassen, die in den Entwickleroptionen verfügbar ist. Wenn Sie Befehlszeilentools verwenden möchten, ist Perfetto ab Android 10 (API-Level 29) verfügbar. Geräte mit früheren Versionen sollten systrace verwenden.

Beachten Sie, dass der Begriff "erster Frame" etwas falsch interpretiert ist, da Anwendungen sich in der Art und Weise, wie sie nach dem Erstellen der Anfangsaktivität starten, erheblich unterscheiden können. Einige Anwendungen setzen die Inflation für mehrere Frames fort, während andere sofort eine sekundäre Aktivität ausführen.

Wir empfehlen, nach Möglichkeit einen reportFullyDrawn-Aufruf (verfügbar für Android 10 und höher) einzufügen, wenn der Startvorgang aus Sicht der Anwendung abgeschlossen ist.

Achten Sie bei diesen System-Traces auf Folgendes:

Konflikt überwachen
Abbildung 1: Der Wettbewerb um mit Monitoring geschützte Ressourcen kann zu erheblichen Verzögerungen beim Start von Anwendungen führen.

Synchrone Binder-Transaktionen
Abbildung 2: Suchen Sie im kritischen Pfad Ihrer Anwendung nach unnötigen Transaktionen.

Gleichzeitige automatische Speicherbereinigung
Abbildung 3: Die gleichzeitige automatische Speicherbereinigung ist üblich und hat relativ geringe Auswirkungen. Sollten Sie dennoch einmal auf Probleme stoßen, sollten Sie dies häufig mit dem Speicher-Profiler von Android Studio untersuchen.

E/A beim Start
Abbildung 4: Prüfen Sie beim Start auf E/A und achten Sie auf lange Verzögerungen.

In Abbildung 4 ist zu beachten, dass andere Prozesse, die gleichzeitig E/A ausführen, zu E/A-Konflikten führen können. Achten Sie also darauf, dass keine anderen Prozesse ausgeführt werden.

Erhebliche Aktivitäten in anderen Threads können den UI-Thread beeinträchtigen. Achten Sie daher beim Start auf Hintergrundarbeiten. Beachten Sie, dass Geräte unterschiedliche CPU-Konfigurationen haben können, sodass die Anzahl der parallel ausgeführten Threads je nach Gerät variieren kann.

Weitere Informationen finden Sie im Leitfaden zu häufigen Ursachen von Verzögerungen.

Arbeitsspeicher-Profiler von Android Studio verwenden

Der Speicher-Profiler von Android Studio ist ein leistungsstarkes Tool, um die Speicherauslastung zu reduzieren, die durch Speicherlecks oder fehlerhafte Nutzungsmuster verursacht werden könnte. Sie bietet eine Live-Ansicht der Objektzuweisungen und -sammlungen.

Zum Beheben von Speicherproblemen in Ihrer Anwendung können Sie den Speicher-Profiler verwenden, um zu verfolgen, warum und wie oft automatische Speicherbereinigungen stattfinden und ob es mögliche Speicherlecks gibt, die dazu führen, dass Ihr Heap mit der Zeit kontinuierlich zunimmt.

Die Profilerstellung für App-Speicher gliedert sich in folgende Schritte:

1. Speicherprobleme erkennen

Zum Erkennen von Arbeitsspeicherproblemen zeichnen Sie zuerst eine Sitzung zur Arbeitsspeicherprofilerstellung für Ihre Anwendung auf. Suchen Sie als Nächstes nach einem Objekt, dessen Arbeitsspeicherbedarf zunimmt, was letztendlich ein Ereignis der automatischen Speicherbereinigung auslöst.

Anzahl der Objekte erhöhen
Abbildung 5: Arbeitsspeicher-Profiler, der erhöhte Zuweisungen von Objekten im Zeitverlauf anzeigt.

Speicherbereinigung
Abbildung 6: Speicher-Profiler, der Ereignisse für die automatische Speicherbereinigung anzeigt.{.:image-caption}

Sobald Sie einen Anwendungsfall identifiziert haben, der die Speicherauslastung erhöht, beginnen Sie mit der Analyse der Ursachen.

2. Speicherauslastungs-Hotspots diagnostizieren

Wählen Sie auf der Zeitachse einen Bereich aus, um sowohl die Zuweisungen als auch die flache Größe zu visualisieren.

Zuweisungen und flache Größe visualisieren
Abbildung 7: Arbeitsspeicher-Profiler, der Zuweisungen und Größen für einen ausgewählten Bereich auf der Zeitachse anzeigt.

Es gibt mehrere Möglichkeiten, diese Daten zu sortieren. In den folgenden Abschnitten finden Sie einige Beispiele dafür, wie Sie mithilfe der einzelnen Ansichten Probleme analysieren können.

Nach Kurs anordnen

Das Anordnen nach Klassen ist nützlich, wenn Sie Klassen finden möchten, die Objekte generieren, die ansonsten im Cache gespeichert oder aus einem Arbeitsspeicherpool wiederverwendet werden sollten.

Stellen Sie sich beispielsweise vor, Sie sehen eine Anwendung,die pro Sekunde 2.000 Objekte der Klasse „Vertex“ erstellt. Dadurch würde die Anzahl der Zuweisungen pro Sekunde um 2.000 erhöht und beim Sortieren nach Klasse angezeigt. Sollten solche Objekte wiederverwendet werden, um diesen Müll zu vermeiden? Wenn die Antwort „Ja“ lautet, ist wahrscheinlich die Implementierung eines Arbeitsspeicherpools erforderlich.

Nach Aufrufstack anordnen

Das Anordnen nach Aufrufstack ist nützlich, wenn es einen Hot Path gibt, in dem Speicher zugewiesen wird, z. B. innerhalb einer Schleife oder einer bestimmten Funktion, die viel Zuteilungsarbeit ausführt. Bei der Anzeige nach Aufrufstack können Sie diese Zuweisungs-Hotspots sehen.

Flache oder beibehaltene Größe

Bei der flachen Größe wird nur der Arbeitsspeicher des Objekts erfasst. Daher ist sie am nützlichsten für das Tracking einfacher Klassen, die hauptsächlich aus Primitiven bestehen.

„Beibehaltene Größe“ zeigt den gesamten Arbeitsspeicher, der vom Objekt direkt zugeteilt wurde, sowie andere zugewiesene Objekte, auf die das Objekt ausschließlich verweist. Sie ist nützlich, um die Speicherauslastung aufgrund komplexer Objekte zu verfolgen, die eine Zuweisung anderer Objekte und nicht nur primitive Felder erfordern. Erstellen Sie mit dem Arbeitsspeicher-Profiler einen Arbeitsspeicher-Dump, um diesen Wert zu erhalten. Die in diesem Heap zugewiesenen Objekte werden der Anzeige hinzugefügt.

Vollständiger Arbeitsspeicher-Dump
Abbildung 8: Sie können jederzeit einen Arbeitsspeicher-Dump erstellen, indem Sie in der Symbolleiste des Arbeitsspeicher-Profilers auf die Dump-Java-Heap-Schaltfläche klicken.

als Spalte hinzugefügt
Abbildung 9: Beim Erstellen eines Speicherdumps wird eine Spalte mit Objektzuweisungen in diesem Heap angezeigt.

3. Auswirkung einer Optimierung messen

Eine leicht zu messende Verbesserung der Arbeitsspeicheroptimierung ist die automatische Speicherbereinigung. Wenn durch eine Optimierung die Speicherauslastung reduziert wird, sollten weniger automatische Speicherbereinigungen angezeigt werden. Um dies zu messen, messen Sie die Zeit zwischen GCs in der Profiler-Zeitachse. Nach der Speicheroptimierung sollten längere Zeiträume zwischen GCs angezeigt werden.

Die letztendliche Wirkung einer solchen Verbesserung des Gedächtnisses ist:

  • Die Anwendung wird aufgrund von Problemen mit unzureichendem Arbeitsspeicher seltener beendet, wenn die Anwendung nicht ständig überlastet ist.
  • Je weniger GCs vorhanden sind, desto besser werden die Messwerte für Verzögerungen. Dies liegt daran, dass GCs CPU-Konflikte verursachen, was dazu führen kann, dass Renderingaufgaben während der GC verzögert werden.