WebView, Android uygulamanızda web içeriği görüntülemenize olanak tanıyan güçlü bir bileşendir. Ancak temelde tam özellikli bir tarayıcı motoru (Chromium) olduğundan önemli bir bellekte kaplanan yer ve karmaşık bir çoklu işlem mimarisine sahiptir.
Teknik arka plan: Çok süreçli mimari
WebView, modern Android destekli cihazlarda güvenliği ve kararlılığı artırmak için çok işlemli bir model kullanır. Uygulamanız bir WebView kullandığında bellek farklı işlemler arasında dağıtılır:
- Tarayıcı süreci (uygulama süreci): Bu, uygulamanızın ana sürecidir. Java
WebViewnesnesini ve Chromium motorunun "tarayıcı" bölümünü içerir. Bu işlem; kullanıcı arayüzünü, ağ isteklerini ve GPU oluşturmayı (doğrudan Android HWUI oluşturma ardışık düzenine entegre edilmiştir) yönetir. Chrome'un aksine WebView'da ayrı bir GPU işlemi yoktur. - Oluşturucu süreci: Bu süreç, HTML'yi ayrıştırmaktan, JavaScript'i çalıştırmaktan ve düzen oluşturmaktan sorumludur. Güvenlik nedeniyle sistemin geri kalanından izole edilmiştir. Şu anda uygulamalar, Chrome'un farklı siteler için genellikle ayrı oluşturucu işlemleri kullanmasının aksine, tüm WebView'lar için yalnızca bir oluşturucu işlemi almaktadır (birkaç nadir özel durum hariç).

Bu neden önemli?
dumpsys meminfo <your_package> kullandığınızda yalnızca tarayıcı süreci (uygulama süreciniz) tarafından kullanılan bellek gösterilir. Oluşturma işlemi tarafından kullanılan bellek ayrı olarak hesaplanır.
Tarayıcı işlemi içinde WebView belleği şu şekilde dağıtılır:
- Java yığını:
WebViewJava sarmalayıcısını ve ilgili nesneleri içerir. - Yerel yığın: Chromium tarayıcı motorunun dahili veri yapılarını, önbelleklerini ve durumunu içerir. PartitionAlloc kullanımı nedeniyle bazı WebView yerel ayırmalarının
dumpsys meminfoiçindeki "Yerel yığın" altında sayılmayabileceğini ve bunun yerine "Diğer" veya "Bilinmiyor" altında görünebileceğini unutmayın. - Paylaşılan bellek: Grafik arabelleklerini ve diğer verileri paylaşmak için kullanılır. Bu,
dumpsys meminfotarafından net bir şekilde kategorize edilmemiş olabilir.
Sorun giderme araçları
Chrome Geliştirici Araçları
WebView'daki (oluşturucu işlemi) belleği analiz etmek için en güçlü araç Chrome Geliştirici Araçları'dır.
Uygulamanızda WebView hata ayıklamayı etkinleştirin:
// NOTE: In production, this should be gated behind a developer setting // or only enabled for debuggable builds to prevent reverse engineering. WebView.setWebContentsDebuggingEnabled(true);Cihazınızı USB ile bağlayın.
Ana makinenizde Chrome'u açın ve
chrome://inspect/#devicesadresine gidin.Uygulamanızı bulup incele'yi tıklayın.
Yığın anlık görüntüleri almak veya JavaScript yığını için tahsis zaman çizelgelerini kaydetmek üzere DevTools penceresinde Bellek sekmesine gidin.
dumpsys meminfo
Bellek dökümünü görmek için adb shell dumpsys meminfo --all <package> simgesini kullanın.
Çıkışta WebView kategorisini ve nesne sayılarını bulun.
Oluşturucuda profil oluşturma
Oluşturucu ayrı bir süreçte çalıştığından, yalnızca uygulamanızın profilini oluşturarak yerel yığın profilini oluşturamazsınız. Oluşturucu sürecinin PID'sini özellikle tanımlamanız gerekir.
Birden fazla WebView etkin olduğunda doğru oluşturucu PID'sini belirlemek için:
dumpsys activitykullanımı:adb shell dumpsys activity processes <your_package_name>mConnectionsbölümünü bulun.ConnectionRecorduygulamanızıSandboxedProcessServiceile bağladığınızı gösteren bir mesaj görürsünüz. Bu sürecin PID'si, oluşturucunuzdur. Örnek:mConnections: - ConnectionRecord{... com.android.memorylab/org.chromium.content.app.SandboxedProcessService0:0 ...}İşlem Adlarını Kontrol Edin: Oluşturucu işlemlerine genellikle
com.google.android.webview:sandboxed_processXveya benzeri bir ad verilir. WebView'u yalnızca bir uygulama kullanıyorsa büyük olasılıkla tek bir WebView olacaktır.
PID'yi aldıktan sonra heapprofd kullanarak profillendirebilirsiniz.
WebView belleği için en iyi uygulamalar
Açıkça imha
Uygulamaların, bir örnekle işleri bittiğinde WebView.destroy() işlevini çağırması beklenir.
WebView, örneklerin çöp toplama işlemine tabi tutulabilmesini ve tüm kaynaklarını otomatik olarak serbest bırakabilmesini sağlamaya çalışsa da bu durumun% 100 garanti edilmesi zordur. Otomatik çöp toplama işlemi çalışsa bile önemli ölçüde gecikebilir ve uygulamanın kaynakları beklenenden çok daha uzun süre tutmasına neden olabilir.
Bir uygulama, WebView.destroy() işlevini uygun zamanda (ör. Activity.onDestroy() içinde) çağırırsa WebView nesnesinin kendisine yönelik bir referansı tutmak önemli yerel kaynakların sızmasına neden olmaz. Etkinlik alanı çöp toplama işlemine tabi tutulduğunda temizleneceğinden, WebView nesnesi yok edildikten sonra Etkinlik alanlarındaki referansların boş değerle değiştirilmesi kesinlikle gerekli değildir.
Alıştırmalar: WebView belleğiyle uygulamalı alıştırma
Alıştırma 1: Çoklu işlem ayak izini gözlemleme
MemoryLab'i başlatın ve uygulamanızın belleğiyle ilgili temel bir ölçüm yapın:
adb shell dumpsys meminfo com.android.memorylabÖrnek referans değeri (aralık):
TOTAL PSS: 18915 KBWebView'i başlat (Normal)'a dokunun.
WebView'da Allocate JS Memory (1000 DIVs) seçeneğine birkaç kez dokunun.
Uygulamanın belleğini tekrar kontrol edin:
adb shell dumpsys meminfo com.android.memorylabUygulama sürecinizdeki belleğin, temel değerle karşılaştırıldığında önemli ölçüde artmadığını gözlemleyin. Bunun nedeni, DOM öğelerinin oluşturucu işleminde olmasıdır.
Oluşturucu işlemini bulun:
adb shell ps -A | grep webview | grep sandboxedÖrnek çıkış:
u0_i9002 14227 1087 1632732 135880 do_epoll_wait 0 S com.google.android.webview:sandboxed_process0Oluşturucu işleminin belleğini kontrol edin (PID'sini kullanarak):
adb shell dumpsys meminfo 14227Oluşturucu işleminin yüksek TOPLAM PSS'sini gözlemleyin. Örnek çalıştırmamızda, birkaç tahsis işleminden sonra ~55 MB'a çıktı. JavaScript ayırmalarının (V8 motoru tarafından işlenir) genellikle Dalvik Heap yerine
dumpsys meminfo'ın Private Other veya Unknown (mmap) bölümlerine katkıda bulunduğunu unutmayın.
2. alıştırma: Java tarafındaki WebView sızıntısı
Sık yapılan bir hata, statik bir alanda veya sızıntıya neden olan uzun ömürlü bir nesnede WebView örneğini tutmaktır. WebView nesnesi, yerel kaynakları ve muhtemelen tüm oluşturucu süreçlerini tutan ağır bir "çapa" olduğundan, bu nesnenin sızdırılması çok maliyetlidir.

- MemoryLab'de Launch WebView (Java Leak)'e (WebView'i başlat (Java sızıntısı)) dokunun.
- Sayfa yüklendikten sonra etkinlik otomatik olarak kapanır (tekrarlanan gezinme ve sızıntı birikimi simülasyonu).
- Düğmeye 4 kez dokunun.
Uygulamanızdaki
WebViewörneklerinin sayısını kontrol edin:adb shell dumpsys meminfo com.android.memorylabEn alttaki Nesneler bölümünü bulun.
WebViewsiçin sayının 4'e yükseldiğini görürsünüz.rango'daki örnek çıkış (4 sızdırılmış örnek):
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: 4Yığın dökümü yakalayın ve sızıntıyı bulmak için AHAT'ı kullanın. Yolunuzda
ahatyoksa Android ağacından oluşturabilirsiniz:# 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.hprofAHAT web arayüzünde (
localhost:8888) genel bellek kullanımını görmek için üst menüdeki allocations (tahsisler) bağlantısını (veya sites (siteler)) tıklayın.
android.webkit.WebViewsınıfını arayın. Tüm canlı örnekleri görmek için örnek sayısını tıklayın. Listede birden fazla örnek görürsünüz.
Sızdırılan
WebViewörneklerinden birini tıklayın. GC kökünden örnek yol bölümüne ilerleyin. Bu öğeninsLeakedWebViewslistesindecom.android.memorylab.WebViewActivitytarafından tutulduğunu görürsünüz.
← Doğal | ↑ Yukarı | Uygulama kodu →