Anwendungsleistung messen – Übersicht

Mithilfe dieses Dokuments kannst du wichtige Leistungsprobleme deiner App identifizieren und beheben.

Wichtige Leistungsprobleme

Es gibt viele Probleme, die zu einer schlechten Leistung einer Anwendung führen können. Hier sind einige häufige Probleme, auf die Sie bei Ihrer Anwendung achten sollten:

Latenz beim Start

Die Startlatenz ist die Zeit, die zwischen dem Antippen des App-Symbols, der Benachrichtigung oder einem anderen Einstiegspunkt und den auf dem Bildschirm angezeigten Daten des Nutzers vergeht.

Nehmen Sie in Ihren Apps die folgenden Ziele beim Start:

  • Kaltstart in weniger als 500 ms Ein Kaltstart tritt auf, wenn sich die gestartete App nicht im Systemspeicher befindet. Dies geschieht, wenn die Anwendung zum ersten Mal nach dem Neustart gestartet oder der Anwendungsprozess vom Nutzer oder vom System beendet wurde.

    Im Gegensatz dazu erfolgt ein Warmstart, wenn die App bereits im Hintergrund ausgeführt wird. Ein Kaltstart erfordert die meiste Arbeit vom System, da alles aus dem Speicher geladen und die App initialisiert werden muss. Kaltstarts sollten maximal 500 ms dauern.

  • Die P95- und P99-Latenzen liegen sehr nahe der Medianlatenz. Wenn der Start der App lange dauert, beeinträchtigt das die Nutzerfreundlichkeit. Die Interprocess Communication (IPCs) und unnötige E/A während des kritischen Pfads des Anwendungsstarts können zu Sperrenkonflikten und zu Inkonsistenzen führen.

Scrollverzögerung

Jank ist der Begriff, der einen visuellen Fehler beschreibt, der auftritt, wenn das System nicht in der Lage ist, Frames rechtzeitig zu erstellen und bereitzustellen, um sie mit der angeforderten Frequenz von 60 Hz oder höher auf dem Bildschirm anzuzeigen. Am deutlichsten ist die Jank beim Scrollen zu sehen, da es hier nicht zu einem flüssig animierten Fluss, sondern zu Problemen kommt. Die Jank tritt auf, wenn die Bewegung für einen oder mehrere Frames pausiert wird, da die App länger zum Rendern des Inhalts benötigt als die Dauer eines Frames im System.

Apps müssen auf Aktualisierungsraten von 90 Hz ausgerichtet sein. Die herkömmlichen Renderingraten betragen 60 Hz. Viele neuere Geräte arbeiten jedoch bei Nutzerinteraktionen wie Scrollen im 90-Hz-Modus. Einige Geräte unterstützen sogar noch höhere Frequenzen von bis zu 120 Hz.

Wenn Sie sehen möchten, welche Aktualisierungsrate ein Gerät zu einem bestimmten Zeitpunkt verwendet, aktivieren Sie im Abschnitt Debugging unter Entwickleroptionen > Aktualisierungsrate anzeigen ein Overlay.

Nicht weiche Übergänge

Dies ist bei Interaktionen wie dem Wechseln zwischen Tabs oder dem Laden einer neuen Aktivität zu sehen. Diese Übergänge müssen flüssige Animationen sein und dürfen keine Verzögerungen oder visuelles Flimmern enthalten.

Leistungsineffizienzen

Arbeit reduziert die Akkulaufzeit und jede unnötige Arbeit reduziert die Akkulaufzeit.

Arbeitsspeicherzuweisungen, die durch das Erstellen neuer Objekte im Code entstehen, können zu erheblicher Arbeit im System führen. Das liegt daran, dass nicht nur die Zuweisungen selbst Aufwand von der Android Runtime (ART) erfordern, sondern auch das spätere Freigeben dieser Objekte (automatische Speicherbereinigung) Zeit und Mühe erfordert. Sowohl die Zuweisung als auch die Erfassung sind viel schneller und effizienter, insbesondere bei temporären Objekten. Früher war es die Best Practice, die Zuweisung von Objekten nach Möglichkeit zu vermeiden. Wir empfehlen aber, so vorzugehen, dass für Ihre Anwendung und Architektur am sinnvollsten ist. Es ist nicht die beste Vorgehensweise, bei Zuweisungen zu sparen, die das Risiko eines nicht wartbaren Codes darstellen, angesichts der Möglichkeiten von ART nicht.

Dies ist jedoch mit Aufwand verbunden. Bedenken Sie also, dass es zu Leistungsproblemen beitragen kann, wenn Sie viele Objekte in der inneren Schleife zuweisen.

Probleme identifizieren

Wir empfehlen den folgenden Workflow, um Leistungsprobleme zu identifizieren und zu beheben:

  1. Identifizieren und analysieren Sie die folgenden kritischen User Journeys:
    • Häufige Startabläufe, z. B. über den Launcher und für Benachrichtigungen
    • Bildschirme, auf denen der Nutzer durch Daten scrollt.
    • Übergänge zwischen Bildschirmen.
    • Lang andauernde Abläufe wie die Navigation oder Musikwiedergabe
  2. Prüfen Sie mit den folgenden Fehlerbehebungstools, was in den vorherigen Abläufen passiert:
    • Perfetto: Hiermit können Sie anhand präziser Zeitdaten sehen, was auf dem gesamten Gerät passiert.
    • Speicher-Profiler: Hiermit können Sie sehen, welche Arbeitsspeicherzuweisungen auf dem Heap stattfinden.
    • Simpleperf: zeigt ein Flamegraph darüber, welche Funktionsaufrufe während eines bestimmten Zeitraums die meiste CPU beanspruchen. Wenn Sie in Systrace etwas finden, das viel Zeit in Anspruch nimmt, Sie aber nicht wissen, warum, kann Simpleperf zusätzliche Informationen bereitstellen.

Um diese Leistungsprobleme zu verstehen und zu beheben, ist es wichtig, die Fehlerbehebung einzelner Testläufe manuell durchzuführen. Sie können die vorherigen Schritte nicht durch die Analyse aggregierter Daten ersetzen. Damit Sie jedoch verstehen, was Nutzer tatsächlich sehen und wann Regressionen auftreten können, ist es wichtig, eine Messwerterfassung in automatischen Tests und in der Praxis einzurichten:

  • Ablauf beim Starten
  • Jank
    • Feldmesswerte
      • Play Console-Frame Vitals: In der Play Console kannst du Messwerte nicht auf eine bestimmte Nutzererfahrung eingrenzen. Sie meldet lediglich die Verzögerung für die gesamte App.
      • Benutzerdefinierte Messung mit FrameMetricsAggregator: Sie können FrameMetricsAggregator verwenden, um Messwerte zu Verzögerungen während eines bestimmten Workflows zu erfassen.
    • Labortests
      • Scrolling mit MacroBenchmark
      • MacroBenchmark erfasst das Frame-Timing mit dumpsys gfxinfo-Befehlen, die eine einzelne User Journey beschreiben. So lassen sich Abweichungen bei der Verzögerung bei bestimmten User Journeys nachvollziehen. Die RenderTime-Messwerte, die Aufschluss darüber geben, wie lange Frames zum Zeichnen benötigt werden, sind für die Identifizierung von Regressionen oder Verbesserungen wichtiger als die Anzahl der inaktiven Frames.

App-Links sind Deeplinks auf Ihrer Website-URL, die bestätigt wurden und zu Ihrer Website gehören. Die folgenden Gründe können dazu führen, dass die Bestätigung von App-Links fehlschlägt.

  • Intent-Filterbereiche: Fügen Sie autoVerify nur bei Intent-Filtern für URLs hinzu, auf die Ihre Anwendung antworten kann.
  • Nicht bestätigte Protokoll-Switches: Nicht bestätigte Weiterleitungen auf Serverseite und Subdomain gelten als Sicherheitsrisiken und schlägt die Überprüfung fehl. Sie führen dazu, dass alle autoVerify-Links fehlschlagen. Beispielsweise kann die Weiterleitung von Links von HTTP zu HTTPS – von „beispiel.de“ zu „www.beispiel.de“ – ohne Überprüfung der HTTPS-Links fehlschlagen. Achten Sie darauf, App-Links zu überprüfen, indem Sie Intent-Filter hinzufügen.
  • Nicht überprüfbare Links: Wenn Sie nicht überprüfbare Links zu Testzwecken hinzufügen, kann das System dazu führen, dass die App-Links für Ihre App nicht verifiziert werden.
  • Unzuverlässige Server: Sorgen Sie dafür, dass Ihre Server eine Verbindung zu Ihren Client-Apps herstellen können.

App für die Leistungsanalyse einrichten

Eine ordnungsgemäße Einrichtung ist unerlässlich, um genaue, wiederholbare und umsetzbare Benchmarks von einer App zu erhalten. Testen Sie das System auf einem System, das sich so nahe wie möglich an der Produktion befindet und zugleich Rauschquellen unterdrückt wird. In den folgenden Abschnitten wird eine Reihe von APK- und systemspezifischen Schritten beschrieben, die Sie zur Vorbereitung einer Testeinrichtung unternehmen können. Einige davon sind anwendungsspezifisch.

Tracepoints

Apps können ihren Code mit benutzerdefinierten Trace-Ereignissen instrumentieren.

Während Traces erfasst werden, verursacht das Tracing einen geringen Aufwand von etwa 5 μs pro Abschnitt, daher sollten Sie es nicht für jede Methode verwenden. Das Tracing größerer Arbeitsschritte von >0,1 ms kann wichtige Einblicke in Engpässe liefern.

Hinweise zu APKs

Debug-Varianten können bei der Fehlerbehebung und Symbolisierung von Stackbeispielen hilfreich sein, haben aber erhebliche Auswirkungen auf die Leistung. Geräte mit Android 10 (API-Level 29) und höher können profileable android:shell="true" in ihrem Manifest verwenden, um die Profilerstellung in Release-Builds zu aktivieren.

Verwenden Sie Ihre produktionstaugliche Codeshrinking-Konfiguration. Abhängig von den Ressourcen, die Ihre Anwendung verwendet, kann dies erhebliche Auswirkungen auf die Leistung haben. Einige ProGuard-Konfigurationen entfernen Tracepoints. Erwägen Sie daher, diese Regeln für die Konfiguration zu entfernen, für die Sie Tests ausführen.

Compilation

Kompiliere deine App auf dem Gerät in einen bekannten Zustand, in der Regel speed oder speed-profile. JIT-Aktivitäten (Hintergrundaktivitäten) können einen erheblichen Leistungsaufwand haben und werden häufig erreicht, wenn Sie das APK zwischen Testläufen neu installieren. Verwenden Sie dazu den folgenden Befehl:

adb shell cmd package compile -m speed -f com.google.packagename

Im Kompilierungsmodus speed wird die Anwendung vollständig kompiliert. Im Modus speed-profile wird die Anwendung gemäß einem Profil der verwendeten Codepfade kompiliert, das während der App-Nutzung erfasst wird. Es kann schwierig sein, Profile konsistent und korrekt zu erfassen. Wenn Sie sie verwenden möchten, sollten Sie also prüfen, ob sie die erwarteten Daten erheben. Die Profile befinden sich an folgendem Ort:

/data/misc/profiles/ref/[package-name]/primary.prof

Mit MacroBenchmark können Sie den Kompilierungsmodus direkt angeben.

Systemaspekte

Kalibrieren Sie Ihre Geräte für Low-Level- und High-Fidelity-Messungen. Sie können A/B-Vergleiche für dasselbe Gerät und dieselbe Betriebssystemversion ausführen. Die Leistung kann selbst zwischen Geräten desselben Gerätetyps stark variieren.

Auf gerooteten Geräten sollten Sie ein lockClocks-Skript für Mikro-Benchmarks verwenden. Diese Skripts erfüllen unter anderem die folgenden Aufgaben:

  • Platzieren Sie CPUs auf einer festen Frequenz.
  • Kleine Kerne deaktivieren und die GPU konfigurieren
  • Drosselung der Überhitzung deaktivieren.

Wir raten davon ab, ein lockClocks-Skript für nutzerfreundliche Tests wie App-Start-, DoU- und Verzögerungstests zu verwenden. Es kann jedoch wichtig sein, um Rauschen in MicroBenchmark-Tests zu reduzieren.

Verwenden Sie nach Möglichkeit ein Test-Framework wie MacroBenchmark, um Rauschen in Ihren Messungen zu reduzieren und Ungenauigkeiten zu vermeiden.

Langsamer App-Start: unnötige Trampolinaktivitäten

Eine Trampolinaktivität kann die App-Startzeit unnötig verlängern. Es ist wichtig zu wissen, ob deine App dies tut. Wie im folgenden Beispiel-Trace gezeigt, folgt ein activityStart unmittelbar auf ein anderes activityStart, ohne dass von der ersten Aktivität Frames gezeichnet wurden.

Alt-Text Abbildung 1: Eine Spur, die Aktivitäten auf dem Trampolin zeigt.

Dies kann sowohl bei einem Benachrichtigungseinstiegspunkt als auch bei einem regulären Anwendungsstartpunkt passieren. Dieses Problem können Sie häufig durch Refaktorierung beheben. Wenn Sie diese Aktivität beispielsweise verwenden, um vor der Ausführung einer anderen Aktivität eine Einrichtung durchzuführen, berücksichtigen Sie diesen Code in eine wiederverwendbare Komponente oder Bibliothek.

Unnötige Zuweisungen, die häufige GCs auslösen

Es kann vorkommen, dass automatische Speicherbereinigungen häufiger stattfinden als von einem Systrace erwartet.

Im folgenden Beispiel ist alle 10 Sekunden während eines Vorgangs mit langer Ausführungszeit ein Hinweis darauf, dass die Anwendung möglicherweise unnötig, aber konsistent im Laufe der Zeit zuweist:

Alt-Text Abbildung 2: Ein Trace mit Abstand zwischen GC-Ereignissen.

Sie stellen auch fest, dass ein bestimmter Aufrufstack die überwiegende Mehrheit der Zuweisungen bei Verwendung des Speicher-Profilers erzeugt. Sie müssen nicht alle Zuweisungen aggressiv entfernen, da dies die Wartung des Codes erschweren kann. Beginnen Sie stattdessen mit der Arbeit an Hotspots von Zuweisungen.

Ruckelnde Frames

Die Grafikpipeline ist relativ kompliziert und es gibt einige Nuancen bei der Entscheidung, ob ein Nutzer letztlich einen entfernten Frame sieht. In einigen Fällen kann die Plattform einen Frame durch Zwischenspeichern „retten“. Sie können jedoch einen Großteil dieser Feinheiten ignorieren, um problematische Frames aus der Perspektive Ihrer App zu identifizieren.

Wenn Frames mit wenig Arbeitsaufwand von der App gezeichnet werden, treten die Choreographer.doFrame()-Tracepoints auf einem Gerät mit 60 fps im Rhythmus von 16,7 ms auf:

Alt-Text Abbildung 3: Ein Trace, das häufige schnelle Frames zeigt.

Wenn Sie herauszoomen und durch den Trace navigieren, stellen Sie manchmal fest, dass die Ausführung der Frames etwas länger dauert.Es ist jedoch auch in Ordnung, da sie nicht mehr als die zugeteilte Zeit von 16,7 ms benötigen:

Alt-Text Abbildung 4: Ein Trace, der häufige schnelle Frames mit periodischen Arbeitsspitzen zeigt.

Wenn Sie eine Störung dieses regelmäßigen Rhythmus sehen, handelt es sich um einen inaktiven Frame, wie in Abbildung 5 dargestellt:

Alt-Text Abbildung 5: Ein Trace, der einen langsamen Frame zeigt.

Sie können üben, sie zu identifizieren.

Alt-Text Abbildung 6: Ein Trace mit mehr langsamen Frames.

In einigen Fällen müssen Sie an einen Tracepoint heranzoomen, um weitere Informationen darüber zu erhalten, welche Ansichten aufgebläht werden oder was RecyclerView tut. In anderen Fällen müssen Sie möglicherweise weitere Details untersuchen.

Weitere Informationen zum Erkennen von langsamen Frames und zum Beheben ihrer Ursachen finden Sie unter Langsames Rendering.

Häufige RecyclerView-Fehler

Die unnötige Entwertung der gesamten Sicherungsdaten von RecyclerView kann zu langen Frame-Renderingzeiten und Verzögerungen führen. Um die Anzahl der zu aktualisierenden Ansichten zu minimieren, entwerten Sie stattdessen nur die Daten, die sich ändern.

Unter Dynamische Daten präsentieren erfahren Sie, wie Sie kostspielige notifyDatasetChanged()-Aufrufe vermeiden, die dazu führen, dass Inhalte nicht vollständig ersetzt werden, sondern aktualisiert werden.

Wenn Sie nicht alle verschachtelten RecyclerView richtig unterstützen, kann das dazu führen, dass die interne RecyclerView jedes Mal vollständig neu erstellt wird. Für jede verschachtelte, innere RecyclerView muss ein RecycledViewPool festgelegt sein, damit Ansichten zwischen jeder inneren RecyclerView wiederverwendet werden können.

Wenn nicht genügend Daten vorab abgerufen oder nicht rechtzeitig vorab abgerufen werden, kann das Erreichen des Endes einer Scroll-Liste zu Unstimmigkeiten führen, wenn ein Nutzer auf weitere Daten vom Server warten muss. Obwohl dies technisch kein Problem ist, da keine Frame-Fristen übersehen werden, können Sie die UX erheblich verbessern, indem Sie den Zeitpunkt und die Menge des Vorabrufs so ändern, dass der Nutzer nicht auf Daten warten muss.

App-Fehler beheben

Es gibt verschiedene Methoden zum Debuggen der Leistung Ihrer App. Im folgenden Video erhalten Sie einen Überblick über das System-Tracing und die Verwendung des Profilers von Android Studio.

Fehler beim Starten von Anwendungen mit Systrace beheben

Einen Überblick über den Anwendungsstartprozess finden Sie unter App-Startzeit. Das folgende Video bietet einen Überblick über das System-Tracing.

Sie können Start-up-Typen in den folgenden Phasen unterscheiden:

  • Kaltstart: Beginnen Sie mit dem Erstellen eines neuen Prozesses ohne gespeicherten Status.
  • Warmstart: erstellt entweder die Aktivität bei der Wiederverwendung des Prozesses oder den Prozess mit dem gespeicherten Status neu.
  • Warmstart: Startet die Aktivität neu und beginnt beim Aufblasen.

Wir empfehlen, Systraces mit der System Tracing App auf dem Gerät zu erfassen. Verwenden Sie für Android 10 und höher Perfetto. Verwenden Sie für Android 9 und niedriger Systrace. Wir empfehlen, Trace-Dateien auch mit dem webbasierten Perfetto Trace Viewer anzusehen. Weitere Informationen finden Sie unter Übersicht über System-Tracing.

Achten Sie auf Folgendes:

  • Monitoring-Konflikte: Der Wettbewerb um Monitor-geschützte Ressourcen kann zu erheblichen Verzögerungen beim Start von Anwendungen führen.
  • Synchrone Bindertransaktionen: Suchen Sie im kritischen Pfad Ihrer Anwendung nach unnötigen Transaktionen. Wenn eine erforderliche Transaktion teuer ist, sollten Sie mit dem zugehörigen Plattformteam zusammenarbeiten, um Verbesserungen vorzunehmen.

  • Gleichzeitige automatische Speicherbereinigung: Dies ist üblich und hat relativ geringe Auswirkungen. Wenn Sie diese jedoch häufig bemerken, sollten Sie sich das mit dem Arbeitsspeicher-Profiler von Android Studio ansehen.

  • E/A: Prüfung auf E/A, die beim Start ausgeführt wurde, und auf lange Wartezeiten achten.

  • Erhebliche Aktivität in anderen Threads: Diese können den UI-Thread beeinträchtigen. Achten Sie daher beim Start auf Hintergrundarbeiten.

Wir empfehlen, reportFullyDrawn aufzurufen, wenn der Startvorgang aus Sicht der App abgeschlossen ist. So werden die Berichte mit App-Start-Messwerten verbessert. Weitere Informationen zur Verwendung von reportFullyDrawn finden Sie im Abschnitt Zeit bis zur vollständigen Anzeige. Sie können RFD-definierte Startzeiten über den Perfetto-Trace-Prozessor extrahieren, woraufhin ein für den Nutzer sichtbares Trace-Ereignis ausgegeben wird.

System Tracing auf dem Gerät verwenden

Mit der Anwendung „System Tracing“ auf Systemebene können Sie einen System-Trace auf einem Gerät erfassen. Mit dieser App können Sie Traces vom Gerät aufzeichnen, ohne es anschließen oder mit adb verbinden zu müssen.

Speicher-Profiler von Android Studio verwenden

Mit dem Speicher-Profiler von Android Studio können Sie die Speicherauslastung prüfen, die durch Speicherlecks oder fehlerhafte Nutzungsmuster verursacht werden kann. Sie bietet eine Live-Ansicht der Objektzuweisungen.

Sie können Speicherprobleme in Ihrer App beheben, indem Sie Informationen aus dem Speicher-Profiler nutzen, um nachzuverfolgen, warum und wie oft automatische Speicherprobleme auftreten.

Führen Sie die folgenden Schritte aus, um ein Profil des Anwendungsarbeitsspeichers zu erstellen:

  1. Speicherprobleme erkennen.

    Zeichnen Sie eine Sitzung zur Arbeitsspeicherprofilerstellung der User Journey auf, auf die Sie sich konzentrieren möchten. Achten Sie auf eine steigende Objektanzahl (siehe Abbildung 7), die schließlich zu GCs führt (siehe Abbildung 8).

    Alt-Text Abbildung 7: Anzahl der Objekte erhöhen

    Alt-Text Abbildung 8: Speicherbereinigung.

    Nachdem Sie den Kaufprozess identifiziert haben, der zu einer höheren Speicherauslastung führt, analysieren Sie die Ursachen nach den Ursachen dafür.

  2. Diagnose von Speicherauslastungs-Hotspots.

    Wählen Sie einen Bereich auf der Zeitachse aus, um sowohl Zuweisungen als auch Flache Größe zu visualisieren, wie in Abbildung 9 dargestellt.

    Alt-Text Abbildung 9: Werte für Allocations und Flache Größe.

    Es gibt mehrere Möglichkeiten, diese Daten zu sortieren. Im Folgenden finden Sie einige Beispiele dafür, wie Sie mit jeder Ansicht Probleme analysieren können.

    • Nach Klasse anordnen: Dies ist hilfreich, wenn Sie Klassen finden möchten, die Objekte generieren, die ansonsten im Cache gespeichert oder aus einem Speicherpool wiederverwendet werden.

      Wenn Sie beispielsweise sehen, dass eine Anwendung pro Sekunde 2.000 Objekte der Klasse „Vertex“ erstellt, wird die Anzahl der Allocations-Objekte pro Sekunde um 2.000 erhöht und beim Sortieren nach Klasse angezeigt. Wenn Sie diese Objekte wiederverwenden möchten, um Speicherbereinigung zu vermeiden, implementieren Sie einen Arbeitsspeicherpool.

    • Nach Aufrufstack anordnen: Dies ist nützlich, wenn Sie herausfinden möchten, wo es einen Hot Path gibt, in dem Speicher zugewiesen wird, z. B. in einer Schleife oder in einer bestimmten Funktion, die eine große Zuweisungsarbeit ausführt.

    • Flache Größe: Erfasst nur den Arbeitsspeicher des Objekts selbst. Es ist nützlich, um einfache Klassen zu verfolgen, die hauptsächlich aus primitiven Werten bestehen.

    • Beibehaltene Größe: Zeigt den gesamten Arbeitsspeicher aufgrund des Objekts und der Verweise an, auf die das Objekt ausschließlich verweist. Sie ist nützlich, um den Speicherbedarf aufgrund komplexer Objekte im Blick zu behalten. Um diesen Wert zu erhalten, erstellen Sie einen vollständigen Speicherdump, wie in Abbildung 10 dargestellt. Beibehaltene Größe wird als Spalte hinzugefügt, wie in Abbildung 11 dargestellt.

      Alt-Text Abbildung 10: Vollständiger Arbeitsspeicher-Dump.

      Spalte „Beibehaltene Größe“.
      Abbildung 11: Beibehaltene Größe.
  3. Messen Sie die Auswirkungen einer Optimierung.

    GCs sind deutlicher und einfacher zu messen, wie sich Speicheroptimierungen auswirken. Wenn durch eine Optimierung die Speicherauslastung reduziert wird, sehen Sie weniger GCs.

    Messen Sie zum Messen der Auswirkungen der Optimierung auf der Profiler-Zeitachse die Zeit zwischen GCs. Sie können dann sehen, dass es länger dauert, bis der Speichervorgang zwischen den Speicherbereinigungsvorgängen abgeschlossen ist.

    Die letztendlichen Auswirkungen einer Verbesserung des Gedächtnisses sind folgende:

    • Nicht genügend Arbeitsspeicher wird wahrscheinlich seltener heruntergefahren, wenn die Anwendung nicht ständig unter Arbeitsspeicherauslastung leidet.
    • Weniger automatische Speicherbereinigungen verbessern die Verzögerungsmesswerte, insbesondere beim P99. Dies liegt daran, dass GCs CPU-Konflikte verursachen, was dazu führen kann, dass Renderingaufgaben während der GC verzögert werden.