O WebView é um componente avançado que permite mostrar conteúdo da Web no seu app Android. No entanto, como ele é essencialmente um mecanismo de navegador completo (Chromium), tem um consumo de memória significativo e uma arquitetura multiprocesso complexa.
Informações técnicas: arquitetura multiprocesso
Em dispositivos modernos com tecnologia Android, o WebView usa um modelo multiprocesso para melhorar a segurança e a estabilidade. Quando o app usa um WebView, a memória é distribuída em diferentes processos:
- Processo do navegador (o processo do app): é o processo principal do aplicativo. Ele contém o objeto
WebViewJava e a parte do "navegador" do mecanismo do Chromium. Esse processo gerencia a interface, as solicitações de rede e a renderização da GPU (integrada diretamente ao pipeline de renderização HWUI do Android). Ao contrário do Chrome, o WebView não tem um processo de GPU separado. - Processo do renderizador: esse processo é responsável por analisar o HTML, executar o JavaScript e o layout. Ele é isolado do restante do sistema por segurança. Atualmente, os apps recebem apenas um processo de renderizador para todos os WebViews (exceto em alguns casos especiais raros), ao contrário do Chrome, que geralmente usa processos de renderizador separados para diferentes sites.

Por que isso é importante para a memória
Ao usar dumpsys meminfo <your_package>, você só vê a memória usada pelo
processo do navegador (o processo do app). A memória usada pelo processo do renderizador é contabilizada separadamente.
Dentro do processo do navegador, a memória do WebView é distribuída como:
- Heap Java: contém o wrapper Java
WebViewe objetos relacionados. - Heap nativo: contém as estruturas de dados internas
, os caches e o estado do mecanismo do navegador Chromium. Devido ao uso do PartitionAlloc, algumas alocações nativas do WebView podem não ser contabilizadas em "Heap nativo" em
dumpsys meminfoe podem aparecer em "Outros" ou "Desconhecido". - Memória compartilhada: usada para compartilhar buffers gráficos e outros dados. Isso pode não ser categorizado claramente por
dumpsys meminfo.
Ferramentas de solução de problemas
Chrome DevTools
A ferramenta mais avançada para analisar a memória dentro do WebView (o processo do renderizador) é o Chrome DevTools.
Ative a depuração do WebView no seu 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);Conecte o dispositivo via USB.
Abra o Chrome na máquina host e acesse
chrome://inspect/#devices.Encontre o app e clique em inspect.
Na janela do DevTools, acesse a guia Memory para fazer snapshots de heap ou gravar cronogramas de alocação para o heap JavaScript.
dumpsys meminfo
Use adb shell dumpsys meminfo --all <package> para conferir uma detalhamento da memória.
Procure a categoria WebView na saída e as contagens de objetos.
Como criar um perfil do renderizador
Como o renderizador é executado em um processo separado, não é possível criar um perfil do heap nativo apenas criando um perfil do app. É necessário identificar o PID do processo do renderizador especificamente.
Para identificar o PID do renderizador correto quando vários WebViews estão ativos:
Use
dumpsys activity:adb shell dumpsys activity processes <your_package_name>Procure a seção
mConnections. Você verá umConnectionRecordvinculando seu app a umSandboxedProcessService. O PID desse processo é o renderizador. Exemplo:mConnections: - ConnectionRecord{... com.android.memorylab/org.chromium.content.app.SandboxedProcessService0:0 ...}Verifique os nomes dos processos: os processos do renderizador geralmente são nomeados como
com.google.android.webview:sandboxed_processXou semelhantes. Se apenas um app estiver usando um WebView, provavelmente haverá apenas um.
Depois de ter o PID, é possível criar um perfil dele usando heapprofd.
Práticas recomendadas para a memória do WebView
Destruição explícita
Espera-se que os apps chamem WebView.destroy() para indicar quando terminarem de usar uma instância.
Embora o WebView tente garantir que as instâncias possam ser coletadas como lixo e liberar todos os recursos automaticamente, isso é difícil de garantir em 100% dos casos. Mesmo quando a coleta automática de lixo funciona, ela pode ser significativamente atrasada, fazendo com que o app mantenha os recursos por muito mais tempo do que o esperado.
Se um app chamar WebView.destroy() no momento apropriado (por exemplo, em
Activity.onDestroy()), manter uma referência ao próprio objeto WebView
não vai vazar recursos nativos significativos. Não há necessidade estrita de referências nulas ao objeto WebView nos campos de atividade após a destruição, porque ele será limpo quando a própria atividade for coletada como lixo.
Exercícios: prática com a memória do WebView
Exercício 1: observação da pegada multiprocesso
Inicie o MemoryLab e faça uma medição de linha de base da memória do app:
adb shell dumpsys meminfo com.android.memorylabLinha de base de exemplo (rango):
TOTAL PSS: 18915 KBToque em Launch WebView (Normal).
No WebView, toque em Allocate JS Memory (1000 DIVs) várias vezes.
Verifique a memória do app novamente:
adb shell dumpsys meminfo com.android.memorylabObserve que a memória no processo do app não aumenta significativamente em comparação com a linha de base. Isso ocorre porque os elementos DOM estão no processo do renderizador.
Encontre o processo do renderizador:
adb shell ps -A | grep webview | grep sandboxedExemplo de saída:
u0_i9002 14227 1087 1632732 135880 do_epoll_wait 0 S com.google.android.webview:sandboxed_process0Verifique a memória do processo do renderizador (usando o PID):
adb shell dumpsys meminfo 14227Observe o PSS TOTAL alto do processo do renderizador. Na nossa execução de amostra, ele saltou para ~55 MB após algumas alocações. As alocações de JavaScript (processadas pelo mecanismo V8) normalmente contribuem para as seções Private Other ou Unknown (mmap) de
dumpsys meminfo, em vez do heap Dalvik.
Exercício 2: vazamento do WebView do lado Java
Um erro comum é manter uma instância WebView em um campo estático ou em um objeto de longa duração que vaza. Como o objeto WebView é uma "âncora" pesada que mantém recursos nativos e potencialmente processos de renderizador inteiros, o vazamento é muito caro.

- No MemoryLab, toque em Launch WebView (Java Leak).
- A atividade será fechada automaticamente após o carregamento da página (simulando a navegação repetida e o acúmulo de vazamentos).
- Toque no botão 4 vezes.
Verifique o número de instâncias
WebViewno seu app:adb shell dumpsys meminfo com.android.memorylabProcure a seção Objects na parte de baixo. Você verá que a contagem de
WebViewsaumentou para 4.Exemplo de saída (4 instâncias vazadas) no 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: 4Capture um heap dump e use o AHAT para encontrar o vazamento. Se você não tiver
ahatno caminho, poderá criá-lo na árvore do 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.hprofNa interface da Web do AHAT (
localhost:8888), clique no link allocations (ou sites) no menu superior para conferir o uso geral da memória.
Pesquise a classe
android.webkit.WebView. Clique na contagem de instâncias para conferir todas as instâncias ativas. Você verá várias instâncias na lista.
Clique em uma das instâncias
WebViewvazadas. Role para baixo até a seção Sample Path from GC Root. Você verá que ela está sendo mantida pela listasLeakedWebViewsemcom.android.memorylab.WebViewActivity.
← Nativo | ↑ Acima | Código do app →