WebView ist eine leistungsstarke Komponente, mit der Sie Webinhalte in Ihrer Android-App anzeigen können. Da es sich im Wesentlichen um eine voll funktionsfähige Browser-Engine (Chromium) handelt, hat sie jedoch einen erheblichen Speicherbedarf und eine komplexe Architektur mit mehreren Prozessen.
Technischer Hintergrund: Architektur mit mehreren Prozessen
Auf modernen Android-Geräten verwendet WebView ein Modell mit mehreren Prozessen, um die Sicherheit und Stabilität zu verbessern. Wenn Ihre App eine WebView verwendet, wird der Arbeitsspeicher auf verschiedene Prozesse verteilt:
- Browserprozess (App-Prozess): Dies ist der Haupt
prozess Ihrer Anwendung. Er enthält das Java-Objekt
WebViewund den „Browser“-Teil der Chromium-Engine. Dieser Prozess verwaltet die UI, Netzwerkanfragen und das GPU-Rendering (direkt in die Android HWUI-Renderingpipeline integriert). Im Gegensatz zu Chrome hat WebView keinen separaten GPU-Prozess. - Renderer-Prozess: Dieser Prozess ist für das Parsen von HTML, die Ausführung von JavaScript und das Layout verantwortlich. Aus Sicherheitsgründen ist er vom Rest des Systems isoliert. Derzeit erhalten Apps nur einen Renderer-Prozess für alle WebViews (mit Ausnahme einiger seltener Sonderfälle). Chrome verwendet oft separate Renderer-Prozesse für verschiedene Websites.

Warum das für den Arbeitsspeicher wichtig ist
Wenn Sie dumpsys meminfo <your_package> verwenden, sehen Sie nur den Arbeitsspeicher, der von
dem Browserprozess (App-Prozess) verwendet wird. Der vom Renderer-Prozess verwendete Arbeitsspeicher wird separat berücksichtigt.
Im Browserprozess wird der WebView-Arbeitsspeicher so verteilt:
- Java-Heap: Enthält den
WebViewJava-Wrapper und zugehörige Objekte. - Nativer Heap: Enthält die internen Daten
strukturen, Caches und den Status der Chromium-Browser-Engine. Aufgrund der Verwendung von PartitionAlloc werden einige native WebView-Zuweisungen in
dumpsys meminfomöglicherweise nicht unter „Native Heap“ gezählt, sondern stattdessen unter „Other“ oder „Unknown“ aufgeführt. - Gemeinsamer Arbeitsspeicher: Wird für die gemeinsame Nutzung von Grafikpuffern und anderen Daten verwendet. Dieser wird von
dumpsys meminfomöglicherweise nicht eindeutig kategorisiert.
Tools zur Fehlerbehebung
Chrome-Entwicklertools
Das leistungsstärkste Tool zum Analysieren des Arbeitsspeichers in der WebView (Renderer-Prozess) sind die Chrome-Entwicklertools.
So aktivieren Sie das WebView-Debugging in Ihrer App:
// NOTE: In production, this should be gated behind a developer setting // or only enabled for debuggable builds to prevent reverse engineering. WebView.setWebContentsDebuggingEnabled(true);Verbinden Sie Ihr Gerät über USB.
Öffnen Sie Chrome auf Ihrem Hostcomputer und rufen Sie
chrome://inspect/#devicesauf.Suchen Sie Ihre App und klicken Sie auf Untersuchen.
Wechseln Sie im Fenster der Entwicklertools zum Tab Arbeitsspeicher, um Heap-Snapshots zu erstellen oder Zuweisungszeitachsen für den JavaScript-Heap aufzuzeichnen.
dumpsys meminfo
Verwenden Sie adb shell dumpsys meminfo --all <package>, um eine Aufschlüsselung des Arbeitsspeichers zu sehen.
Suchen Sie in der Ausgabe nach der Kategorie WebView und der Anzahl der Objekte.
Renderer-Profil erstellen
Da der Renderer in einem separaten Prozess ausgeführt wird, können Sie seinen nativen Heap nicht einfach durch die Profilerstellung Ihrer App analysieren. Sie müssen die PID des Renderer-Prozesses speziell identifizieren.
So identifizieren Sie die richtige Renderer-PID, wenn mehrere WebViews aktiv sind:
Verwenden Sie
dumpsys activity:adb shell dumpsys activity processes <your_package_name>Suchen Sie nach dem Abschnitt
mConnections. Sie sehen einenConnectionRecord, der Ihre App mit einemSandboxedProcessServiceverknüpft. Die PID dieses Prozesses ist Ihr Renderer. Beispiel:mConnections: - ConnectionRecord{... com.android.memorylab/org.chromium.content.app.SandboxedProcessService0:0 ...}Prozessnamen prüfen: Renderer-Prozesse haben in der Regel den Namen
com.google.android.webview:sandboxed_processXoder ähnlich. Wenn nur eine App eine WebView verwendet, gibt es wahrscheinlich nur eine.
Sobald Sie die PID haben, können Sie sie mit heapprofd analysieren.
Best Practices für den WebView-Arbeitsspeicher
Explizite Zerstörung
Apps müssen WebView.destroy() aufrufen, um anzugeben, wann sie mit einer Instanz fertig sind.
WebView versucht zwar, dafür zu sorgen, dass Instanzen automatisch per Garbage Collection erfasst und alle Ressourcen freigegeben werden, aber das ist nicht in allen Fällen garantiert. Auch wenn die automatische Garbage Collection funktioniert, kann sie sich erheblich verzögern, sodass die App Ressourcen viel länger als erwartet belegt.
Wenn eine App WebView.destroy() zum richtigen Zeitpunkt aufruft (z.B. in
Activity.onDestroy()), werden durch das Beibehalten eines Verweises auf das WebView Objekt selbst
keine nennenswerten nativen Ressourcen verloren. Es ist nicht unbedingt erforderlich, Verweise auf das WebView-Objekt in Aktivitätsfeldern nach der Zerstörung auf null zu setzen, da es bereinigt wird, wenn die Aktivität selbst per Garbage Collection erfasst wird.
Übungen: Praktische Arbeit mit dem WebView-Arbeitsspeicher
Übung 1: Arbeitsspeicherbedarf bei mehreren Prozessen beobachten
Starten Sie MemoryLab und nehmen Sie eine Baseline-Messung des Arbeitsspeichers Ihrer App vor:
adb shell dumpsys meminfo com.android.memorylabBeispiel-Baseline (rango) :
TOTAL PSS: 18915 KBTippen Sie auf WebView starten (normal).
Tippen Sie in der WebView mehrmals auf JS-Arbeitsspeicher zuweisen (1000 DIVs).
Prüfen Sie noch einmal den Arbeitsspeicher der App:
adb shell dumpsys meminfo com.android.memorylabDer Arbeitsspeicher in Ihrem App-Prozess steigt im Vergleich zur Baseline nicht wesentlich an. Das liegt daran, dass sich die DOM-Elemente im Renderer-Prozess befinden.
Suchen Sie den Renderer-Prozess:
adb shell ps -A | grep webview | grep sandboxedBeispielausgabe:
u0_i9002 14227 1087 1632732 135880 do_epoll_wait 0 S com.google.android.webview:sandboxed_process0Prüfen Sie den Arbeitsspeicher des Renderer-Prozesses (anhand seiner PID):
adb shell dumpsys meminfo 14227Beachten Sie die hohe TOTAL PSS des Renderer-Prozesses. In unserem Beispiel ist sie nach einigen Zuweisungen auf ~55 MB gestiegen. JavaScript-Zuweisungen (die von der V8-Engine verarbeitet werden) tragen in der Regel zu den Abschnitten Private Other oder Unknown (mmap) von
dumpsys meminfobei und nicht zum Dalvik-Heap.
Übung 2: WebView-Speicherleck auf der Java-Seite
Ein häufiger Fehler ist, eine WebView-Instanz in einem statischen Feld oder in einem langlebigen Objekt zu behalten, das ein Speicherleck verursacht. Da das WebView-Objekt ein schwerer „Anker“ ist, der native Ressourcen und möglicherweise ganze Renderer-Prozesse belegt, ist ein Speicherleck sehr kostspielig.

- Tippen Sie in MemoryLab auf WebView starten (Java-Speicherleck).
- Die Aktivität wird automatisch geschlossen, nachdem die Seite geladen wurde (simuliert wiederholte Navigation und Ansammlung von Speicherlecks).
- Tippen Sie viermal auf die Schaltfläche.
Prüfen Sie die Anzahl der
WebView-Instanzen in Ihrer App:adb shell dumpsys meminfo com.android.memorylabSuchen Sie unten nach dem Abschnitt Objects. Die Anzahl der
WebViewsist auf 4 gestiegen.Beispielausgabe (4 Speicherlecks) auf rango:
Objects Views: 51 ViewRootImpl: 5 AppContexts: 14 Activities: 5 Assets: 38 AssetManagers: 0 Local Binders: 55 Proxy Binders: 77 Parcel memory: 41 Parcel count: 68 Death Recipients: 3 WebViews: 4Erfassen Sie einen Heap-Dump und verwenden Sie AHAT , um das Speicherleck zu finden. Wenn
ahatnicht in Ihrem Pfad vorhanden ist, können Sie es aus dem Android-Baum erstellen:# Dump heap from device adb shell am dumpheap com.android.memorylab /data/local/tmp/heap.hprof adb pull /data/local/tmp/heap.hprof # Run ahat using the built JAR (found in out/host/linux-x86/framework/) java -jar out/host/linux-x86/framework/ahat.jar -p 8888 heap.hprofKlicken Sie in der AHAT-Weboberfläche (
localhost:8888) im oberen Menü auf den Link allocations (oder sites), um die Arbeitsspeichernutzung zu sehen.
Suchen Sie nach der Klasse
android.webkit.WebView. Klicken Sie auf die Anzahl der Instanzen , um alle aktiven Instanzen zu sehen. In der Liste sollten mehrere Instanzen zu sehen sein.
Klicken Sie auf eine der
WebView-Instanzen mit Speicherleck. Scrollen Sie nach unten zum Abschnitt Sample Path from GC Root. Sie sehen, dass sie von der ListesLeakedWebViewsincom.android.memorylab.WebViewActivitybelegt wird.
← Nativ | ↑ Nach oben | App-Code →