Gezinti Kemeri Bileşeni yanlış pozitif bellek sızıntısı oluşturabilir mi?


14

Bellek sızıntıları ve bunlara neyin sebep olabileceği konusunda temel bir bilgim var. Bu yüzden benim kodumda bir sorun var mı yoksa yanlış bir pozitif mi anlamıyorum. Proje küçük olmadığından kodun hangi kısmını paylaşmam gerektiğini bilmiyorum. Ama sadece yorumlarda bana bildirin ve gerekli kodu ekleyeceğim.

Navigasyon arch bileşenini kullanıyorum ve MVVM modelini takip ediyorum. LeakCanary kütüphanesini daha sonra projenin geliştirilmesinde ekledim ve ekranlar arasında gezindiğimde hemen muhafaza edilen örnekler hakkında uyarılar vermeye başladı.

Arka yığını parçaları eklediğimde sorun oluşur. Arka istifin her ilave parçasında tutulan örneklerin sayacı artar. 5 eşik değerine ulaştığında, LeakCanary yığını atar ve rapor sağlar.

Ancak geri düğmesine tıklayıp önceki ekranlara dönersem, muhafaza edilen örneklerin sayacı azalır ve sonunda, 1. ekrana geri döndüğünde tüm muhafaza edilen örnekler kaybolur.

Ben yığın analiz raporları bakarsanız, CoordinatorLayoutxml içinde bir referans olan değişken coordinatorLayout sızdırılmış diyor . Değişkeni ve tüm kullanımını kaldırır ve uygulamayı tekrar çalıştırırsam aynı sorunu görüyorum, ancak şimdi xml'de başka bir görünüme başvuru olan başka bir değişkenle. LeakCanary'nin sızıntı olarak bildirdiği tüm görünümleri ve kullanımlarını kaldırmaya çalıştım. Bir dediğimde TextViewsadece bir metin olarak ayarlamak için kullanılan, onViewCreatedve başka hiçbir yerde kullanılan, benim kodda bir sorun olduğunu şüphe etmeye başladı sızıyor.

Yaşam döngüsü yöntemi çağrılarını parçalar halinde analiz ettim ve önceki parça için yeni ekrana gittiğimde onDestroyView, çağrılana kadar olan ve olmayan tüm yöntemlerin farkına vardım onDestroy. Geri tıkladığımda onDestroy, arka yığının üstündeki parça denir ve tutulan örnekler sayacı azalır.

Gezinme bileşeninin bir yığın örneğini arka yığıntayken tuttuğundan ve LeakCanary'nin bir sızıntı olarak gördüğünden şüpheleniyorum.

Yanıtlar:


24

Arka yığındaki Parçalar bu şekilde çalışır (ve Gezinme yalnızca mevcut Parça API'larını kullanır): Parçanın görünümü yok edilir, ancak Parçanın kendisi yok edilmez - CREATEDsiz geri düğmesine basana ve Fragman'a dönene kadar durumları korunur (bundan sonra onCreateView()tekrar çağrılacak ve geri döneceksiniz RESUMED).

Gereğince Fragments: Geçmiş, Bugün ve Gelecek konuşma , geleceğin birine değiştirir Fragments geliyor doğrusu iki ayrı Lifecyle olmasındansa geri yığın Fragments yok etmek seçeneğindeki bir tercih olduğunu. Bu henüz mevcut değil.

Görünümler için referanslarınızı onDestroyViewiptal etmelisiniz, çünkü görünümün artık Parça sistemi tarafından kullanılmadığının işareti ve Görünüm'e sürekli referansınız yoksa güvenli bir şekilde toplanabilir.


2
Android View Binding bu sorunu çözüyor mu? Görünüm Bağlama görünümleri (belki de bağlayıcı nesnenin kendisi) başvuru otomatik olarak onDestroyViewGörünüm Bağlama ile 'boş' olup olmadığını hakkında herhangi bir belge bulamıyorum .
Tim Malseed

3
@TimMalseed - ciltleme nesnesine olan başvurunuzu kendiniz iptal etmeniz gerekir, otomatik hiçbir şey yoktur.
ianhanniballake

1
@Emmanuel - sahip olduğu Görünümler için zor bir başvuru olduğu için başvurunuzu bağlayıcı nesneye bırakmanız gerekir.
ianhanniballake

1
@Emmanuel - her zaman bir özellik isteği gönderebilirsiniz !
ianhanniballake

1
@Emmanuel - Ben kesinlikle davranış değişikliği olacağını düşünüyorum (bu bayrak ayrı bir tercih olabilir anlamına gelebilir), ama doğru LifecycleOwner sahip bellek sorunları bir sürü düzeltmek için yeterli bilgi olacaktır.
ianhanniballake
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.