Arbeitsspeicherverwaltung – Übersicht

Die Android Runtime (ART) und die Dalvik-virtuelle Maschine verwenden Auslagerung und Speicherzuordnung (mmapping), um den Arbeitsspeicher zu verwalten. Das bedeutet, dass jeder Speicher, der von einer App geändert wird – sei es durch Zuweisen neuer Objekte oder durch Berühren von zugeordneten Seiten –, im RAM verbleibt und nicht ausgelagert werden kann. Die einzige Möglichkeit, Speicherplatz in einer App freizugeben, besteht darin, die Objektverweise freizugeben, die die App enthält, und den Speicher so für den Garbage Collector verfügbar zu machen. Mit einer Ausnahme: Alle Dateien, die ohne Änderung mmapped werden, z. B. Code, können aus dem RAM ausgelagert werden, wenn das System diesen Speicher an anderer Stelle verwenden möchte.

Auf dieser Seite wird erläutert, wie Android App-Prozesse und die Speicherzuweisung verwaltet. Weitere Informationen zum effizienteren Verwalten des Arbeitsspeichers in Ihrer App finden Sie unter Verwaltung des Arbeitsspeichers Ihrer App.

Automatische Speicherbereinigung

In einer verwalteten Arbeitsspeicherumgebung wie der ART- oder Dalvik-VM wird jede Arbeitsspeicherzuweisung erfasst. Sobald festgestellt wurde, dass ein Speicherbereich vom Programm nicht mehr verwendet wird, wird er ohne Eingreifen des Programmierers wieder an den Heap zurückgegeben. Der Mechanismus zum Zurückgewinnen nicht verwendeter Arbeitsspeicher in einer verwalteten Arbeitsspeicherumgebung wird als Garbage Collection bezeichnet. Die Garbage Collection hat zwei Ziele: Datenobjekte in einem Programm zu finden, auf die in Zukunft nicht mehr zugegriffen werden kann, und die von diesen Objekten verwendeten Ressourcen wiederzuverwenden.

Der Speicher-Heap von Android ist nutzungsabhängig, d. h., es gibt verschiedene Speicherbereiche, die basierend auf der erwarteten Lebensdauer und Größe eines zugewiesenen Objekts erfasst werden. Beispielsweise gehören kürzlich zugewiesene Objekte zur jungen Generation. Wenn ein Objekt lange genug aktiv bleibt, kann es in eine ältere Generation und dann in eine dauerhafte Generation hochgestuft werden.

Für jede Heap-Generation gibt es eine eigene Obergrenze für die Menge an Arbeitsspeicher, die Objekte dort belegen können. Sobald eine Generation voll wird, führt das System ein Ereignis zur automatischen Speicherbereinigung aus, um Arbeitsspeicher freizugeben. Die Dauer der Garbage Collection hängt davon ab, welche Generation von Objekten beseitigt wird und wie viele aktive Objekte in jeder Generation vorhanden sind.

Auch wenn die Garbage Collection recht schnell sein kann, kann sie sich dennoch auf die Leistung Ihrer App auswirken. Sie haben in der Regel keinen Einfluss darauf, wann ein Garbage-Collection-Ereignis in Ihrem Code auftritt. Das System hat eine Reihe von Kriterien, anhand derer bestimmt wird, wann die automatische Speicherbereinigung durchgeführt werden soll. Wenn die Kriterien erfüllt sind, beendet das System die Ausführung des Prozesses und beginnt mit der Garbage Collection. Wenn die Garbage Collection mitten in einem intensiven Verarbeitungs-Loop wie einer Animation oder während der Musikwiedergabe erfolgt, kann sich die Verarbeitungszeit verlängern. Diese Erhöhung kann dazu führen, dass die Codeausführung in Ihrer App den empfohlenen Grenzwert von 16 ms für ein effizientes und flüssiges Frame-Rendering überschreitet.

Außerdem kann Ihr Codefluss Aufgaben ausführen, die dazu führen, dass Garbage Collection-Ereignisse häufiger auftreten oder länger als normal dauern. Wenn Sie beispielsweise in jedem Frame einer Alpha-Blending-Animation mehrere Objekte im innersten Teil einer For-Schleife zuweisen, kann der Speicher-Heap mit vielen Objekten überlastet werden. In diesem Fall führt der Garbage Collector mehrere Garbage Collection-Ereignisse aus und die Leistung Ihrer App kann beeinträchtigt werden.

Allgemeinere Informationen zur Garbage Collection finden Sie unter Garbage Collection.

Erinnerung teilen

Damit alles, was benötigt wird, in den RAM passt, versucht Android, RAM-Seiten zwischen Prozessen zu teilen. Dies kann auf eine der folgenden Arten geschehen:

  • Jeder App-Prozess wird von einem vorhandenen Prozess namens Zygote abgespalten. Der Zygote-Prozess wird gestartet, wenn das System hochfährt, und lädt gängigen Framework-Code und Ressourcen (z. B. Aktivitätsthemen) Um einen neuen App-Prozess zu starten, teilt das System den Zygote-Prozess und lädt dann den Code der App in den neuen Prozess. Mit diesem Ansatz können die meisten RAM-Seiten, die für Framework-Code und ‑Ressourcen zugewiesen sind, für alle App-Prozesse gemeinsam verwendet werden.
  • Die meisten statischen Daten werden in einen Prozess mmapped. Mit dieser Methode können Daten zwischen Prozessen freigegeben und bei Bedarf ausgelagert werden. Beispiele für statische Daten: Dalvik-Code (durch Platzieren in einer vorab verknüpften .odex-Datei für die direkte MMAP-Zuordnung), App-Ressourcen (durch Entwerfen der Ressourcentabelle als Struktur, die MMAP-fähig ist, und durch Ausrichten der ZIP-Einträge der APK) und traditionelle Projektelemente wie nativer Code in .so-Dateien.
  • An vielen Stellen teilt Android denselben dynamischen RAM zwischen Prozessen mithilfe von explizit zugewiesenen gemeinsamen Speicherbereichen (entweder mit ashmem oder gralloc) auf. Beispielsweise verwenden Fensteroberflächen gemeinsam genutzten Arbeitsspeicher zwischen der App und dem Bildschirmkompositeur und Cursor-Buffer gemeinsam genutzten Arbeitsspeicher zwischen dem Inhaltsanbieter und dem Client.

Aufgrund der umfangreichen Nutzung von gemeinsam genutztem Arbeitsspeicher ist es schwierig, die Speichernutzung Ihrer App zu ermitteln. Methoden zur korrekten Bestimmung der Speichernutzung Ihrer App werden unter RAM-Nutzung untersuchen beschrieben.

App-Speicher zuweisen und zurückfordern

Der Dalvik-Heap ist für jeden App-Prozess auf einen einzelnen Bereich des virtuellen Arbeitsspeichers beschränkt. Dadurch wird die Größe des logischen Heaps definiert, die bei Bedarf wachsen kann, jedoch nur bis zu einem vom System für jede App festgelegten Grenzwert.

Die logische Größe des Heaps entspricht nicht der Menge an physischem Arbeitsspeicher, die vom Heap verwendet wird. Wenn Android den Heap Ihrer App untersucht, berechnet es einen Wert namens Proportional Set Size (PSS). Dieser Wert berücksichtigt sowohl schmutzige als auch saubere Seiten, die mit anderen Prozessen gemeinsam genutzt werden. Die Menge ist jedoch proportional zur Anzahl der Apps, die sich diesen RAM teilen. Dieser Wert (PSS) wird vom System als physischer Arbeitsspeicherbedarf betrachtet. Weitere Informationen zum PSS finden Sie im Leitfaden RAM-Nutzung untersuchen.

Der Dalvik-Heap komprimiert die logische Größe des Heaps nicht. Das bedeutet, dass Android den Heap nicht defragmentiert, um Speicherplatz freizugeben. Android kann die Größe des logischen Heaps nur dann verkleinern, wenn am Ende des Heaps nicht verwendeter Speicherplatz vorhanden ist. Das System kann jedoch den vom Heap verwendeten physischen Arbeitsspeicher reduzieren. Nach der Garbage Collection durchsucht Dalvik den Heap, sucht nach nicht verwendeten Seiten und gibt diese dann mit madvise an den Kernel zurück. Daher sollten die Zuweisung und Freigabe großer Bereiche dazu führen, dass der gesamte (oder fast der gesamte) verwendete physische Arbeitsspeicher wiederverwendet wird. Das Zurückfordern von Speicher aus kleinen Zuweisungen kann jedoch viel weniger effizient sein, da die Seite, die für eine kleine Zuweisung verwendet wird, möglicherweise noch mit etwas anderem geteilt wird, das noch nicht freigegeben wurde.

App-Speicherplatz begrenzen

Um eine funktionierende Multitasking-Umgebung aufrechtzuerhalten, legt Android für jede App eine feste Obergrenze für die Heap-Größe fest. Die genaue Obergrenze für die Heap-Größe variiert je nach Gerät, je nachdem, wie viel RAM insgesamt verfügbar ist. Wenn Ihre App die Heap-Kapazität erreicht hat und versucht, mehr Speicher zuzuweisen, kann eine OutOfMemoryError ausgegeben werden.

In einigen Fällen möchten Sie möglicherweise das System abfragen, um genau zu ermitteln, wie viel Heap-Speicher auf dem aktuellen Gerät verfügbar ist. So können Sie beispielsweise feststellen, wie viele Daten sicher in einem Cache gespeichert werden können. Sie können das System durch Aufrufen von getMemoryClass() nach dieser Zahl fragen. Diese Methode gibt eine Ganzzahl zurück, die die Anzahl der Megabyte angibt, die für den Heap Ihrer App verfügbar sind.

Apps wechseln

Wenn Nutzer zwischen Apps wechseln, speichert Android Apps, die sich nicht im Vordergrund befinden, also nicht für den Nutzer sichtbar sind oder keinen Dienst im Vordergrund ausführen, z. B. die Musikwiedergabe, im Cache. Wenn ein Nutzer beispielsweise zum ersten Mal eine App startet, wird ein Prozess dafür erstellt. Wenn der Nutzer die App jedoch verlässt, wird dieser Prozess nicht beendet. Der Prozess wird im Cache des Systems gespeichert. Wenn der Nutzer später zur App zurückkehrt, verwendet das System den Prozess wieder, wodurch das App-Wechseln schneller wird.

Wenn Ihre App einen im Cache gespeicherten Prozess hat und Ressourcen behält, die sie derzeit nicht benötigt, wirkt sich Ihre App – auch wenn der Nutzer sie nicht verwendet – auf die Gesamtleistung des Systems aus. Wenn dem System Ressourcen wie Arbeitsspeicher ausgehen, werden Prozesse im Cache beendet. Das System berücksichtigt auch Prozesse, die den meisten Arbeitsspeicher belegen, und kann sie beenden, um RAM freizugeben.

Hinweis:Je weniger Arbeitsspeicher Ihre App im Cache verbraucht, desto höher ist die Wahrscheinlichkeit, dass sie nicht beendet wird und schnell fortgesetzt werden kann. Je nach den aktuellen Systemanforderungen können jedoch zwischengespeicherte Prozesse jederzeit beendet werden, unabhängig von ihrer Ressourcennutzung.

Weitere Informationen dazu, wie Prozesse im Cache gespeichert werden, wenn sie nicht im Vordergrund ausgeführt werden, und wie Android entscheidet, welche Prozesse beendet werden können, finden Sie im Leitfaden Prozesse und Threads.

Speicher-Stresstest

Obwohl Probleme mit Arbeitsspeicherengpässen auf Geräten der Oberklasse seltener auftreten, können sie dennoch für Nutzer auf Geräten mit wenig RAM zu Problemen führen, z. B. auf Geräten mit Android (Go-Version). Es ist wichtig, diese speicherintensive Umgebung nachzubilden, damit Sie Instrumentierungstests schreiben können, um das App-Verhalten zu überprüfen und die Nutzung für Ihre Nutzer auf Geräten mit wenig Arbeitsspeicher zu verbessern.

Stresstest der Anwendung

Der Stresstest für Anwendungen (stressapptest) ist ein Speicherschnittstellentest, mit dem realistische Situationen mit hoher Auslastung simuliert werden können, um verschiedene Speicher- und Hardwareeinschränkungen für Ihre App zu testen. Da Sie Zeit- und Speichereinschränkungen definieren können, können Sie Instrumentationen schreiben, um reale Situationen mit hoher Speicherauslastung zu überprüfen. Mit den folgenden Befehlen können Sie beispielsweise die statische Bibliothek in Ihr Datendateisystem hochladen, sie ausführbar machen und einen Stresstest für 20 Sekunden mit 990 MB ausführen:
    adb push stressapptest /data/local/tmp/
    adb shell chmod 777 /data/local/tmp/stressapptest
    adb shell /data/local/tmp/stressapptest -s 20 -M 990

  

Weitere Informationen zur Installation des Tools, zu gängigen Argumenten und zur Fehlerbehandlung finden Sie in der stressapptest-Dokumentation.

Beobachtungen zu stressapptest

Mit Tools wie stressapptest können Sie eine Speicherzuweisung anfordern, die größer ist als der verfügbare freie Speicher. Diese Art von Anfrage kann verschiedene Warnungen auslösen, die Sie als Entwickler kennen sollten. Aufgrund von wenig verfügbarem Arbeitsspeicher können drei Hauptwarnungen ausgegeben werden:
  • SIGABRT: Dies ist ein fataler, nativer Absturz Ihres Prozesses, da eine Größe angefordert wird, die größer als der kostenlose Arbeitsspeicher ist, während das System bereits unter Speicherdruck steht.
  • SIGQUIT: Erzeugt einen Core-Speicher-Dump und beendet den Prozess, wenn er von Ihrem Instrumentierungstest erkannt wird.
  • TRIM_MEMORY_EVENTS: Diese Callbacks sind unter Android 4.1 (API-Level 16) und höher verfügbar und liefern detaillierte Speicherwarnungen für Ihren Prozess.