Bu dokümanda, bellek yönetimi kapsamında Android uygulamaları için en iyi uygulamalarla ilgili yönergelere (ör. Uygulamanızın belleğini yönetme) uyduğunuz varsayılmaktadır.
Giriş
Bellek sızıntısı, bir bilgisayar programı artık ihtiyaç duyulmayan ayrılmış belleği serbest bırakmadığında ortaya çıkan bir tür kaynak sızıntısıdır. Sızıntı, uygulamanın işletim sisteminden sahip olduğundan daha fazla bellek istemesine ve dolayısıyla uygulamanın çökmesine neden olabilir. Kaynakların düzgün şekilde kullanılmaması veya artık gerekli olmadığında dinleyicilerin kaydının silinmemesi gibi bazı yanlış uygulamalar Android uygulamalarında bellek sızıntısına neden olabilir.
Bu dokümanda, kodunuzdaki bellek sızıntılarını önlemeye, tespit etmeye ve çözmeye yardımcı olacak bazı en iyi uygulamalar sunulmaktadır. Bu dokümandaki yöntemleri denediyseniz ve SDK'larımızda bellek sızıntısı olduğundan şüpheleniyorsanız Google SDK'larıyla ilgili sorunları bildirme başlıklı makaleyi inceleyin.
Destek ekibiyle iletişime geçmeden önce
Bir bellek sızıntısını Google destek ekibine bildirmeden önce, hatanın kodunuzda olmadığından emin olmak için bu belgede verilen hata ayıklama adımlarının yanı sıra en iyi uygulamaları uygulayın. Bu adımlar sorununuzu çözebilir. Çözüm bulamazsa Google Destek Ekibi'nin size yardımcı olması için gereken bilgileri oluşturur.
Bellek sızıntısını önleme
Google SDK'larını kullanan kodda hafıza sızıntısı sorunlarının en yaygın nedenlerinden bazılarını önlemek için aşağıdaki en iyi uygulamalardan yararlanın.
Android uygulamaları için en iyi uygulamalar
Android uygulamanızda aşağıdakilerin tümünü yaptığınızdan emin olun:
- Kullanılmayan kaynakları serbest bırakın.
- Artık ihtiyaç duyulmadığında dinleyicilerin kaydını iptal edin.
- Gerekmediğinde görevleri iptal edin.
- Kaynakları serbest bırakmak için yaşam döngüsü yöntemlerini iletin.
- SDK'ların en son sürümlerini kullanın
Bu uygulamaların her biri hakkında ayrıntılı bilgi için aşağıdaki bölümlere bakın.
Kullanılmayan kaynakları serbest bırakma
Android uygulamanız bir kaynak kullandığında, artık gerekli olmadığında kaynağı serbest bıraktığınızdan emin olun. Aksi takdirde, uygulamanız bu kaynakları kullanmayı bıraktıktan sonra bile kaynak hafıza kullanmaya devam eder. Daha fazla bilgi için Android dokümanlarında Etkinlik yaşam döngüsü bölümünü inceleyin.
GeoSDK'lerde eski Google Haritalar referanslarını kaldırma
NavigationView veya MapView kullanılarak önbelleğe alınan bir GoogleMap'in bellek sızıntısına neden olabileceği yaygın bir hatadır. GoogleMap, alındığı NavigationView veya MapView ile 1'e 1 ilişkiye sahiptir. Bir GoogleMap'in önbelleğe alınmadığından veya NavigationView#onDestroy veya MapView#onDestroy çağrıldığında referansın serbest bırakıldığından emin olmanız gerekir. NavigationSupportFragment, MapSupportFragment veya bu görünümleri sarmalayan kendi parçanızı kullanıyorsanız referans, Fragment#onDestroyView içinde serbest bırakılmalıdır.
class NavFragment : SupportNavigationFragment() {
var googleMap: GoogleMap?
override fun onCreateView(
inflater: LayoutInflater,
parent: ViewGroup?,
savedInstanceState: Bundle?,
): View {
super.onCreateView(inflater,parent,savedInstanceState)
getMapAsync{map -> googleMap = map}
}
override fun onDestroyView() {
googleMap = null
}
}
Artık ihtiyaç duyulmayan dinleyicilerin kaydını silme
Android uygulamanız bir etkinlik için dinleyici kaydettiğinde (ör. düğme tıklaması veya bir görünümün durumundaki değişiklik), uygulamanın artık etkinliği izlemesi gerekmediğinde dinleyicinin kaydını sildiğinizden emin olun. Aksi takdirde, dinleyiciler uygulamanızla ilgili işlemleri tamamladıktan sonra bile bellek kullanmaya devam eder.
Örneğin, uygulamanızın Navigasyon SDK'sını kullandığını ve varış etkinliklerini dinlemek için aşağıdaki dinleyiciyi çağırdığını varsayalım:
addArrivalListener
yöntemi çağırır. Ayrıca, artık varış etkinliklerini izlemesi gerekmediğinde removeArrivalListener
yöntemini de çağırmalıdır.
var arrivalListener: Navigator.ArrivalListener? = null
fun registerNavigationListeners() {
arrivalListener =
Navigator.ArrivalListener {
...
}
navigator.addArrivalListener(arrivalListener)
}
override fun onDestroy() {
navView.onDestroy()
if (arrivalListener != null) {
navigator.removeArrivalListener(arrivalListener)
}
...
super.onDestroy()
}
Gerekmediğinde görevleri iptal etme
Bir Android uygulaması, indirme veya ağ isteği gibi asenkron bir görev başlattığında, görev tamamlandığında iptal ettiğinizden emin olun. Görev iptal edilmezse uygulamanın görevi tamamlamasından sonra bile arka planda çalışmaya devam eder.
En iyi uygulamalar hakkında daha fazla bilgi için Android dokümanlarında Uygulamanızın belleğini yönetme başlıklı makaleyi inceleyin.
Kaynakları serbest bırakmak için yaşam döngüsü yöntemlerini yönlendirme
Uygulamanız Navigasyon veya Haritalar SDK'sını kullanıyorsa yaşam döngüsü yöntemlerini (kalın olarak gösterilir) navView
adresine yönlendirerek kaynakları serbest bıraktığınızdan emin olun. Bunu Navigasyon SDK'sında NavigationView
veya Haritalar ya da Navigasyon SDK'sında MapView
kullanarak yapabilirsiniz. Doğrudan NavigationView
ve MapView
yerine SupportNavigationFragment
veya SupportMapFragment
kullanabilirsiniz. Destek parçaları, yaşam döngüsü yöntemlerinin yönlendirilmesini yönetir.
class NavViewActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
navView = ...
navView.onCreate(savedInstanceState)
...
}
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
navView.onSaveInstanceState(savedInstanceState)
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
navView.onTrimMemory(level)
}
/* Same with
override fun onStart()
override fun onResume()
override fun onPause()
override fun onConfigurationChanged(...)
override fun onStop()
override fun onDestroy()
*/
}
SDK'ların en son sürümlerini kullanın
Google SDK'ları yeni özellikler, hata düzeltmeleri ve performans iyileştirmeleriyle sürekli olarak güncellenir. Bu düzeltmeleri almak için uygulamanızdaki SDK'ları güncel tutun.
Bellek sızıntısı sorunlarını ayıklama
Bu belgenin önceki bölümlerinde yer alan tüm geçerli önerileri uyguladıktan sonra hâlâ bellek sızıntısı görüyorsanız hata ayıklama için bu süreci uygulayın.
Başlamadan önce Android'in belleği nasıl yönettiği hakkında bilgi sahibi olmanız gerekir. Bilgi için Android Bellek yönetimine genel bakış başlıklı makaleyi okuyun.
Bellek sızıntılarını ayıklamak için aşağıdaki işlemi uygulayın:
- Sorunu yeniden oluşturun. Bu adım, hata ayıklama için gereklidir.
- Bellek kullanımının beklenip beklenmediğini kontrol edin. Sızıntı gibi görünen artan kullanımın aslında uygulamanızı çalıştırmak için gereken bellek olmadığından emin olun.
- Yüksek düzeyde hata ayıklama. Hata ayıklama için kullanabileceğiniz çeşitli yardımcı programlar vardır. Android'deki bellek sorunlarını gidermeye yardımcı olan üç farklı standart araç grubu vardır: Android Studio, Perfetto ve Android Debug Bridge (adb) komut satırı yardımcı programları.
- Uygulamanızın bellek kullanımını kontrol edin. Bir yığın dökümü ve tahsis izlemesi alın ve ardından bunları analiz edin.
- Bellek sızıntılarını düzeltin.
Aşağıdaki bölümlerde bu adımlar ayrıntılı olarak açıklanmıştır.
1. Adım: Sorunu yeniden oluşturun
Sorunu yeniden oluşturamadıysanız önce bellek sızıntısına neden olabilecek senaryoları göz önünde bulundurun. Sorunun yeniden oluşturulduğunu biliyorsanız doğrudan bir yığın dökümüne bakmak işe yarayabilir. Ancak, uygulamanın başlatılması veya rastgele bir zamanda yığın dökümünü almanız, bir sızıntıyı tetikleyecek koşulları etkinleştirmediğiniz anlamına gelebilir. Sorunu yeniden oluşturmaya çalışırken çeşitli senaryoları göz önünde bulundurun:
Hangi özellik grubu etkinleştirilir?
Sızıntıyı tetikleyen belirli bir kullanıcı işlemi dizisi var mı?
- Bu sırayı etkinleştirmeyi birden çok kez denediniz mi?
Uygulama hangi yaşam döngüsü durumlarında bulundu?
- Farklı yaşam döngüsü durumlarında birden fazla iterasyon denediniz mi?
Sorunu SDK'ların en son sürümünde yeniden oluşturabileceğinizden emin olun. Önceki sürümdeki sorun zaten düzeltilmiş olabilir.
2. adım: Uygulamanın bellek kullanımının beklenen düzeyde olup olmadığını kontrol edin
Her özellik için ek bellek gerekir. Farklı senaryolarda hata ayıklama yaparken bunun beklenen bir kullanım olup olmadığını veya gerçekten bir bellek sızıntısı olup olmadığını düşünün. Örneğin, farklı özellikler veya kullanıcı görevleri için aşağıdaki olasılıkları göz önünde bulundurun:
Büyük olasılıkla sızıntı: Senaryoyu birden fazla iterasyonla etkinleştirmek, zaman içinde bellek kullanımının artmasına neden olur.
Beklenen bellek kullanımı: Senaryo durdurulduktan sonra bellek geri alınır.
Olası beklenenden bellek kullanımı: Bellek kullanımı bir süre boyunca artar, ardından azalır. Bu durum, sınırlı bir önbellekten veya beklenenden başka bir bellek kullanımından kaynaklanabilir.
Uygulama davranışı büyük olasılıkla beklenen bellek kullanımıysa sorunu, uygulamanızın belleğini yöneterek çözebilirsiniz. Yardım için Uygulamanızın belleğini yönetme başlıklı makaleyi inceleyin.
3. adım: Yüksek düzeyde hata ayıklama
Bir bellek sızıntısı için hata ayıklama işlemi yaparken üst düzeyden başlayın ve olasılıkları daralttıktan sonra ayrıntılı inceleme yapın. Öncelikle zaman içinde sızıntı olup olmadığını analiz etmek için aşağıdaki üst düzey hata ayıklama araçlarından birini kullanın:
Android Studio Bellek Profil Aracı (Önerilir)
Android Debug Bridge (adb) komut satırı yardımcı programları
Android Studio Memory Profiler
Bu araç, kullanılan belleğin görsel bir histogramini gösterir. Yığın dökümleri ve ayırma izleme de aynı arayüzden tetiklenebilir. Bu araç, varsayılan öneridir. Daha fazla bilgi için Android Studio Bellek Profilleyicisi başlıklı makaleyi inceleyin.
Perfetto Bellek Sayaçları
Perfetto, çeşitli metrikleri izleme konusunda hassas kontrol sağlar ve tüm metrikleri tek bir histogramde sunar. Daha fazla bilgi için Perfetto Bellek Sayaçları başlıklı makaleyi inceleyin.
Android Debug Bridge (adb) komut satırı yardımcı programları
Perfetto ile izleyebileceğiniz verilerin çoğu, doğrudan sorgulayabileceğiniz bir adb
komut satırı yardımcı programı olarak da kullanılabilir. Birkaç önemli örnek:
Meminfo, belirli bir zamanda ayrıntılı hafıza bilgilerini görmenize olanak tanır.
İşlem istatistikleri, zaman içinde bazı önemli toplu istatistikler sağlar.
Burada dikkat edilmesi gereken önemli bir istatistik, uygulamanın zaman içinde ihtiyaç duyduğu maksimum fiziksel bellek alanı (maxRSS) boyutudur. MaxPSS o kadar doğru olmayabilir. Doğruluğu artırmanın bir yolu için adb shell dumpsys procstats --help –start-testing
işaretine bakın.
Ayırma izleme
Tahsis izleme, belleğin tahsis edildiği yığın izlemeyi ve belleğin boşaltılıp boşaltılmadığını tanımlar. Bu adım, özellikle yerel koddaki sızıntıları tespit ederken yararlıdır. Bu araç yığın izlemeyi tanımladığından, temel nedenin hata ayıklamasını hızlıca yapmanın veya sorunun nasıl yeniden oluşturulacağını anlamanın mükemmel bir yolu olabilir. Ayırma izlemeyi kullanma adımları için Ayırma izleme ile yerel kodda bellek hatalarını ayıklama başlıklı makaleyi inceleyin.
4. Adım: Bir yığın dökümü kullanarak uygulamanızın bellek kullanımını kontrol edin
Bellek sızıntısını tespit etmenin bir yolu, uygulamanızın yığın dökümünü alıp sızıntıyı kontrol etmektir. Yığın dökümü, bir uygulamanın belleğindeki tüm nesnelerin anlık görüntüsüdür. Bellek sızıntılarını ve bellekle ilgili diğer sorunları teşhis etmek için kullanılabilir.
Android Studio, GC tarafından düzeltilemeyen bellek sızıntılarını algılayabilir. Bir yığın dökümünü yakaladığınızda Android Studio, hâlâ erişilebilir durumda olan ancak zaten yok edilmiş bir etkinlik veya parça olup olmadığını kontrol eder.
- Bellek yığını dökümü alın.
- Bellek sızıntısı bulmak için yığın dökümünü analiz edin.
- Bellek sızıntılarını düzeltin.
Ayrıntılar için aşağıdaki bölümlere bakın.
Yığın dökümü yakalama
Bellek yığını dökümü yakalamak için Android Debug Bridge'i (adb) veya Android Studio Bellek Profilleyici'yi kullanabilirsiniz.
Yığın dökümünü yakalamak için adb'yi kullanma
adb kullanarak yığın dökümü almak için aşağıdaki adımları uygulayın:
- Android cihazınızı bilgisayarınıza bağlayın.
- Komut istemi açın ve adb araçlarının bulunduğu dizine gidin.
Bir yığın dökümünü yakalamak için şu komutu çalıştırın :
adb shell am dumpheap my.app.name $PHONE_FILE_OUT
Yığın dökümünü almak için şu komutu çalıştırın:
adb pull $PHONE_FILE_OUT $LOCAL_FILE.
Bellek yığını dökümü yakalamak için Android Studio'yu kullanma
Android Studio Bellek Profilleyici'yi kullanarak bir yığın dökümü yakalamak için Android Yığın dökümü yakalama bölümündeki adımları uygulayın.
Bellek sızıntısı bulmak için yığın dökümünü analiz etme
Bir yığın dökümü yakaladıktan sonra, Android Studio Bellek Profilleyici'yi kullanarak bu dökümanı analiz edebilirsiniz. Bunu yapmak için şu adımları uygulayın:
Android Studio'da Android projenizi açın.
Çalıştır'ı, ardından Hata ayıklama yapılandırmasını seçin.
Android Profilleyici sekmesini açın.
Hafıza'yı seçin.
Yığın dökümünü aç'ı ve oluşturduğunuz yığın dökümünü seçin. Bellek profilleyici, uygulamanızın bellek kullanımının grafiğini gösterir.
Yığın dökümünü analiz etmek için grafiği kullanın:
Artık kullanılmayan nesneleri tanımlayın.
Çok fazla bellek kullanan nesneleri belirleme
Her nesnenin ne kadar bellek kullandığını görebilirsiniz.
Bellek sızıntısının kaynağını daraltmak veya bulmak ve sorunu gidermek için bu bilgileri kullanın.
5. adım: Bellek sızıntılarını düzeltin
Bellek sızıntısının kaynağını belirledikten sonra sorunu düzeltebilirsiniz. Android uygulamalarınızdaki bellek sızıntılarının düzeltilmesi, uygulamalarınızın performansını ve kararlılığını artırmaya yardımcı olur. Ayrıntılar senaryoya bağlı olarak değişir. Ancak aşağıdaki öneriler yardımcı olabilir:
Uygulamanızın, Uygulamanızın belleğini yönetme başlıklı Android konusunda önerilen şekilde bellek ayırdığından ve bellek ayırmayı sonlandırdığından emin olun.
Kullanılmayan kodları veya kaynakları uygulamanızdan kaldırın. Android uygulamalarıyla ilgili ayrıntılar için Android uygulamalarıyla ilgili en iyi uygulamalar başlıklı makaleyi inceleyin.
Diğer hata ayıklama araçları
Bu adımlar tamamlandıktan sonra hâlâ bellek sızıntısını bulup düzeltmediyseniz aşağıdaki araçları deneyin:
- Ayrıntılandırma izleme özelliğiyle yerel koddaki bellekte hata ayıklama.
- LeakCanary ile sızıntıları tespit edin.
Ayırma izleme özelliğiyle yerel kodda bellek hatalarını ayıklayın
Doğrudan doğal kod kullanmıyor olsanız bile Google SDK'ları da dahil olmak üzere birçok yaygın Android kitaplığı doğal kod kullanır. Bellek sızıntısının yerel kodda olduğunu düşünüyorsanız bu sorunu gidermek için kullanabileceğiniz çeşitli araçlar vardır. Android Studio veya heapprofd (Perfetto ile de uyumludur) ile ayırma izleme, bellek sızıntısının olası nedenlerini belirlemenin mükemmel bir yoludur ve genellikle hata ayıklamanın en hızlı yoludur.
Ayırma izlemenin bir diğer avantajı da, sonuçları bir yığınta bulunabilecek hassas bilgileri içermeden paylaşmanıza olanak tanımasıdır.
LeakCanary ile sızıntıları tespit etme
LeakCanary, Android uygulamalarındaki bellek sızıntılarını tespit etmek için kullanılan güçlü bir araçtır. LeakCanary'yi uygulamanızda nasıl kullanacağınız hakkında daha fazla bilgi edinmek için LeakCanary'yi ziyaret edin.
Google SDK'larıyla ilgili sorunları bildirme
Bu belgedeki yöntemleri denediyseniz ve SDK'larımızda bellek sızıntısı olduğundan şüpheleniyorsanız aşağıdaki bilgilerden olabildiğince fazlasını ekleyerek müşteri desteğiyle iletişime geçin:
Bellek sızıntısını yeniden oluşturma adımları. Adımlar karmaşık kodlama gerektiriyorsa sorunun tekrarlandığı kodu örnek uygulamamıza kopyalamanız ve sızıntıyı tetiklemek için kullanıcı arayüzünde uygulanması gereken ek adımları sağlamanız yararlı olabilir.
Sorunun yeniden oluşturulduğu uygulamanızdan alınan yığın dökümleri. Bellek kullanımının önemli ölçüde arttığını gösteren iki farklı zamanda yığın dökümleri alın.
Doğal bir bellek sızıntısı bekleniyorsa heapprofd'den ayırma izleme çıktısını paylaşın.
Sızıntı durumunu yeniden oluşturduktan sonra alınan bir hata raporu.
Bellekle ilgili kilitlenmelerin yığın izlemeleri.
Önemli not: Yığın izlemeler genellikle bir bellek sorununu ayıklamak için tek başına yeterli değildir. Bu nedenle, diğer bilgi biçimlerinden birini de sağladığınızdan emin olun.