WebView est un composant puissant qui vous permet d'afficher du contenu Web dans votre application Android. Toutefois, comme il s'agit essentiellement d'un moteur de navigateur complet (Chromium), il occupe une quantité de mémoire importante et possède une architecture multi-processus complexe.
Informations techniques : architecture multi-processus
Sur les appareils Android modernes, WebView utilise un modèle multi-processus pour améliorer la sécurité et la stabilité. Lorsque votre application utilise un composant WebView, la mémoire est répartie entre différents processus :
- Processus du navigateur (processus de l'application) : il s'agit du processus principal de votre application. Il contient l'objet Java
WebViewet la partie "navigateur" du moteur Chromium. Ce processus gère l'interface utilisateur, les requêtes réseau et le rendu GPU (intégré directement au pipeline de rendu HWUI Android). Contrairement à Chrome, WebView ne dispose pas d'un processus GPU distinct. - Processus de rendu : ce processus est responsable de l'analyse du code HTML, de l'exécution du code JavaScript et de la mise en page. Il est isolé du reste du système pour des raisons de sécurité. Actuellement, les applications n'obtiennent qu'un seul processus de rendu pour tous les composants WebView (à l'exception de quelques cas particuliers rares), contrairement à Chrome qui utilise souvent des processus de rendu distincts pour différents sites.

Utilité pour la mémoire
Lorsque vous utilisez dumpsys meminfo <your_package>, vous ne voyez que la mémoire utilisée par
le processus du navigateur (processus de votre application). La mémoire utilisée par le processus de rendu est comptabilisée séparément.
Dans le processus du navigateur, la mémoire WebView est répartie comme suit :
- Tas Java : contient le wrapper Java
WebViewet les objets associés. - Tas natif : contient les structures de données internes
, les caches et l'état du moteur de navigateur Chromium. Notez qu'en raison de l'utilisation de PartitionAlloc, certaines allocations natives WebView peuvent ne pas être comptabilisées sous "Native Heap" (Tas natif) dans
dumpsys meminfoet peuvent apparaître sous "Other" (Autre) ou "Unknown" (Inconnu). - Mémoire partagée : utilisée pour partager des tampons graphiques et d'autres données. Elle peut ne pas être clairement classée par
dumpsys meminfo.
Outils de dépannage
Outils pour les développeurs Chrome
L'outil le plus puissant pour analyser la mémoire dans WebView (le processus de rendu) est celui des outils pour les développeurs Chrome.
Activez le débogage WebView dans votre application :
// NOTE: In production, this should be gated behind a developer setting // or only enabled for debuggable builds to prevent reverse engineering. WebView.setWebContentsDebuggingEnabled(true);Connectez votre appareil à l'aide d'un câble USB.
Ouvrez Chrome sur votre machine hôte et accédez à
chrome://inspect/#devices.Recherchez votre application, puis cliquez sur inspect (inspecter).
Dans la fenêtre des outils pour les développeurs, accédez à l'onglet Memory (Mémoire) pour prendre des instantanés du tas ou enregistrer des chronologies d'allocation pour le tas JavaScript.
dumpsys meminfo
Utilisez adb shell dumpsys meminfo --all <package> pour afficher une répartition de la mémoire.
Recherchez la catégorie WebView dans le résultat et le nombre d'objets.
Profiler le moteur de rendu
Étant donné que le moteur de rendu s'exécute dans un processus distinct, vous ne pouvez pas profiler son tas natif en profilant simplement votre application. Vous devez identifier spécifiquement le PID du processus de rendu.
Pour identifier le PID de rendu correct lorsque plusieurs composants WebView sont actifs :
Utilisez
dumpsys activity:adb shell dumpsys activity processes <your_package_name>Recherchez la section
mConnections. Vous verrez unConnectionRecordqui associe votre application à unSandboxedProcessService. Le PID de ce processus est votre moteur de rendu. Exemple :mConnections: - ConnectionRecord{... com.android.memorylab/org.chromium.content.app.SandboxedProcessService0:0 ...}Vérifiez les noms des processus : les processus de rendu sont généralement nommés
com.google.android.webview:sandboxed_processXou similaire. Si une seule application utilise un composant WebView, il n'y en aura probablement qu'un seul.
Une fois que vous disposez du PID, vous pouvez le profiler à l'aide de heapprofd.
Bonnes pratiques pour la mémoire WebView
Destruction explicite
Les applications sont censées appeler WebView.destroy() pour indiquer quand elles ont terminé avec une instance.
Bien que WebView tente de s'assurer que les instances peuvent être collectées comme déchets et libérer automatiquement toutes leurs ressources, il est difficile de le garantir dans 100% des cas. Même lorsque la récupération automatique de mémoire fonctionne, elle peut être considérablement retardée, ce qui fait que l'application conserve les ressources beaucoup plus longtemps que prévu.
Si une application appelle WebView.destroy() au moment approprié (par exemple, dans
Activity.onDestroy()), la conservation d'une référence à l'objet WebView lui-même
ne fuira aucune ressource native importante. Il n'est pas strictement nécessaire de définir des références nulles à l'objet WebView dans les champs d'activité après sa destruction, car il sera nettoyé lorsque l'activité elle-même sera collectée comme déchets.
Exercices : pratique avec la mémoire WebView
Exercice 1 : observer l'empreinte multi-processus
Lancez MemoryLab et effectuez une mesure de référence de la mémoire de votre application :
adb shell dumpsys meminfo com.android.memorylabExemple de référence (rango) :
TOTAL PSS: 18915 KBAppuyez sur Launch WebView (Normal) (Lancer WebView [Normal]).
Dans WebView, appuyez plusieurs fois sur Allocate JS Memory (1000 DIVs) (Allouer de la mémoire JS [1 000 DIV]).
Vérifiez à nouveau la mémoire de l'application :
adb shell dumpsys meminfo com.android.memorylabNotez que la mémoire du processus de votre application n'augmente pas de manière significative par rapport à la référence. En effet, les éléments DOM se trouvent dans le processus de rendu.
Recherchez le processus de rendu :
adb shell ps -A | grep webview | grep sandboxedExemple de résultat :
u0_i9002 14227 1087 1632732 135880 do_epoll_wait 0 S com.google.android.webview:sandboxed_process0Vérifiez la mémoire du processus de rendu (à l'aide de son PID) :
adb shell dumpsys meminfo 14227Observez le PSS TOTAL élevé du processus de rendu. Dans notre exemple d'exécution, il est passé à ~55 Mo après quelques allocations. Notez que les allocations JavaScript (gérées par le moteur V8) contribuent généralement aux sections Private Other (Autre privé) ou Unknown (Inconnu) (mmap) de
dumpsys meminfo, plutôt qu'au tas Dalvik.
Exercice 2 : fuite WebView côté Java
Une erreur courante consiste à conserver une instance WebView dans un champ statique ou dans un objet à longue durée de vie qui fuit. Étant donné que l'objet WebView est une "ancre" lourde qui conserve les ressources natives et potentiellement des processus de rendu entiers, sa fuite est très coûteuse.

- Dans MemoryLab, appuyez sur Launch WebView (Java Leak) (Lancer WebView [Fuite Java]).
- L'activité se ferme automatiquement une fois la page chargée (simulant une navigation répétée et une accumulation de fuites).
- Appuyez quatre fois sur le bouton.
Vérifiez le nombre d'instances
WebViewdans votre application :adb shell dumpsys meminfo com.android.memorylabRecherchez la section Objects (Objets) en bas de la page. Vous verrez que le nombre de
WebViewsest passé à 4.Exemple de résultat (4 instances ayant fui) sur 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: 4Capturez une empreinte de la mémoire et utilisez AHAT pour trouver la fuite. Si
ahatne figure pas dans votre chemin d'accès, vous pouvez le créer à partir de l'arborescence Android :# 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.hprofDans l'interface Web AHAT (
localhost:8888), cliquez sur le lien allocations (allocations) ou sites dans le menu supérieur pour afficher l'utilisation globale de la mémoire.
Recherchez la classe
android.webkit.WebView. Cliquez sur son instance count (nombre d'instances) pour afficher toutes les instances actives. Plusieurs instances devraient s'afficher dans la liste.
Cliquez sur l'une des instances
WebViewayant fui. Faites défiler la page jusqu'à la section Sample Path from GC Root (Exemple de chemin d'accès à partir de la racine GC). Vous verrez qu'elle est conservée par la listesLeakedWebViewsdanscom.android.memorylab.WebViewActivity.
← Natif | ↑ Haut | Code de l'application →