Bu belgede, bellek yönetimiyle ilgili en iyi uygulama yönergelerini (ör. Uygulamanızın belleğini yönetme) uyguladığınız varsayılmaktadır.
Giriş
Bellek sızıntısı, bir bilgisayar programının artık ihtiyaç duyulmayan ayrılmış belleği serbest bırakmaması durumunda meydana gelen bir kaynak sızıntısı türüdür. Sızıntı, uygulamanın işletim sisteminden kullanabildiğinden daha fazla bellek istemesine ve dolayısıyla uygulamanın çökmesine neden olabilir. Bir dizi uygunsuz uygulama, Android uygulamalarında bellek sızıntılarına neden olabilir. Örneğin, kaynakların uygun şekilde elden çıkarılmaması veya dinleyicilerin artık gerekmediğinde kaydının silinmemesi.
Bu belgede, kodunuzdaki bellek sızıntılarını önlemenize, tespit etmenize ve çözmenize yardımcı olacak bazı en iyi uygulamalar sunulmaktadır. Bu belgedeki 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
Bellek sızıntısını Google Destek Ekibi'ne bildirmeden önce, hatanın kodunuzda olmadığından emin olmak için bu belgede sağlanan hata ayıklama adımlarıyla birlikte en iyi uygulamaları izleyin. Bu adımlar sorununuzu çözebilir. Çözmezse Google Destek Ekibi'nin size yardımcı olmak için ihtiyaç duyduğu bilgileri oluşturur.
Bellek sızıntılarını önleme
Google SDK'larını kullanan kodda bellek sızıntısının en yaygın nedenlerinden bazılarını önlemek için aşağıdaki en iyi uygulamalardan yararlanın.
Android uygulamalarıyla ilgili 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ı silin.
- Gerekli olmayan görevleri iptal edin.
- Kaynakları serbest bırakmak için yaşam döngüsü yöntemlerini iletin.
- SDK'ların en yeni sürümlerini kullanın
Bu uygulamaların her biriyle ilgili 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, kaynaklar uygulamanız bunları kullanmayı bitirdikten sonra bile bellek kullanmaya devam eder. Daha fazla bilgi için Android belgelerindeki Etkinlik yaşam döngüsü başlıklı makaleyi inceleyin.
GeoSDK'lerde eski GoogleMap referanslarını serbest bırakma
GoogleMap'in, NavigationView veya MapView kullanılarak önbelleğe alınması durumunda bellek sızıntısına neden olabileceği yaygın bir hatadır. GoogleMap, alındığı NavigationView veya MapView ile bire bir ilişkiye sahiptir. GoogleMap'in önbelleğe alınmadığından veya NavigationView#onDestroy ya da 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ç duyulmadığında dinleyicilerin kaydını silme
Android uygulamanız bir etkinlik için (ör. düğme tıklama veya görünüm durumunda değişiklik) dinleyici kaydettiğinde, uygulamanın artık etkinliği izlemesi gerekmediğinde dinleyicinin kaydını kaldırdığınızdan emin olun. Aksi takdirde, dinleyiciler uygulamanız onlarla işini bitirdikten sonra bile bellek kullanmaya devam eder.
Örneğin, uygulamanızın Navigation SDK'yı kullandığını ve varış etkinliklerini dinlemek için aşağıdaki işleyiciyi çağırdığını varsayalım:
addArrivalListener
varış etkinliklerini dinlemek için kullanılan yöntem, 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()
}
Gerekli olmayan görevleri iptal etme
Bir Android uygulaması, indirme veya ağ isteği gibi eşzamansız bir göreve başladığında görev tamamlandığında iptal ettiğinizden emin olun. İptal edilmeyen görevler, uygulama tamamlandıktan sonra bile arka planda çalışmaya devam eder.
En iyi uygulamalar hakkında daha fazla bilgi için Android belgelerindeki 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 iletme
Uygulamanızda Navigation veya Haritalar SDK'sı kullanılıyorsa yaşam döngüsü yöntemlerini (kalın olarak gösterilmiştir) navView
'ya 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. Ayrıca, doğrudan NavigationView
ve MapView
kullanmak yerine sırasıyla SupportNavigationFragment
veya SupportMapFragment
da kullanabilirsiniz. Destek parçaları, yaşam döngüsü yöntemlerinin yönlendirilmesini sağlar.
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ı sürekli olarak yeni özellikler, hata düzeltmeleri ve performans iyileştirmeleriyle güncellenir. Bu düzeltmeleri almak için uygulamanızdaki SDK'ları güncel tutun.
Bellek sızıntılarını ayıklama
Bu belgenin önceki bölümlerinde yer alan tüm geçerli önerileri uyguladıktan sonra bellek sızıntıları görmeye devam ederseniz hata ayıklama için bu süreci izleyin.
Başlamadan önce Android'in belleği nasıl yönettiğini bilmeniz gerekir. Daha fazla bilgi için Android Bellek yönetimine genel bakış başlıklı makaleyi inceleyin.
Bellek sızıntılarını ayıklamak için şu işlemi uygulayın:
- Sorunu yeniden oluşturun. Bu adım, hata ayıklama için gereklidir.
- Bellek kullanımının beklendiği gibi olup olmadığını 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ığını kontrol edin.
- Üst düzeyde hata ayıklama. Hata ayıklamak için kullanabileceğiniz çeşitli yardımcı programlar vardır. Android'deki bellek sorunlarında hata ayıklamaya yardımcı olan üç farklı standart araç seti 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. Yığın dökümü ve ayırma izleme alıp analiz etme
- 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 öncelikle bellek sızıntısına yol açabilecek senaryoları göz önünde bulundurun. Sorunun yeniden oluşturulduğunu biliyorsanız doğrudan yığın dökümüne bakmak işe yarayabilir. Ancak, uygulama başlatılırken veya başka bir rastgele zamanda yalnızca bir yığın dökümü alırsanız sızıntıyı tetikleyecek koşulları etkinleştirmemiş olabilirsiniz. Sorunu yeniden oluşturmaya çalışırken çeşitli senaryoları göz önünde bulundurun:
Hangi özellikler etkinleştirilir?
Hangi kullanıcı işlemleri sırası sızıntıyı tetikliyor?
- Bu sırayı etkinleştirmek için birden fazla deneme yaptınız mı?
Uygulama hangi yaşam döngüsü durumlarından geçti?
- Farklı yaşam döngüsü durumlarında birden fazla yineleme denediniz mi?
Sorunu SDK'ların en son sürümünde yeniden oluşturabildiğinizden emin olun. Önceki bir sürümdeki sorun düzeltilmiş olabilir.
2. adım: Uygulamanın bellek kullanımının normal 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 aslında bir bellek sızıntısı olup olmadığını göz önünde bulundurun. Ö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 yinelemeyle etkinleştirmek, bellek kullanımının zaman içinde artmasına neden olur.
Beklenen bellek kullanımı: Senaryo durdurulduktan sonra bellek geri kazanılır.
Muhtemelen beklenen bellek kullanımı: Bellek kullanımı bir süre artar ve sonra azalır. Bu durum, sınırlı bir önbellekten veya beklenen diğer bellek kullanımlarından kaynaklanabilir.
Uygulama davranışının beklenen bellek kullanımı olduğu düşünülüyorsa sorun, uygulamanızın belleğini yöneterek çözülebilir. Yardım için Uygulamanızın belleğini yönetme başlıklı makaleyi inceleyin.
3. adım: Üst düzeyde hata ayıklama
Bellek sızıntısını ayıklarken yüksek bir seviyeden başlayın ve olasılıkları daralttıktan sonra ayrıntılara inin. Ö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 Memory Profiler (Önerilir)
Android Debug Bridge (adb) komut satırı yardımcı programları
Android Studio Memory Profiler
Bu araç, kullanılan belleğin görsel histogramını 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 Memory Profiler başlıklı makaleyi inceleyin.
Perfetto Bellek Sayaçları
Perfetto, çeşitli metriklerin izlenmesi üzerinde hassas kontrol sağlar ve tüm bunları tek bir histogramda sunar. Daha fazla bilgi için Perfetto Bellek Sayaçları bölümüne bakın.
Android Debug Bridge (adb) komut satırı yardımcı programları
Perfetto ile izleyebileceğiniz birçok şey, doğrudan sorgulayabileceğiniz bir adb
komut satırı yardımcı programı olarak da kullanılabilir. Bu konuda birkaç önemli örnek şunlardır:
Meminfo, belirli bir zamandaki ayrıntılı bellek bilgilerini görmenizi sağlar.
Procstats, zaman içinde bazı önemli toplu istatistikler sağlar.
Burada dikkat edilmesi gereken önemli bir istatistik, uygulamanın zaman içinde gerektirdiği maksimum fiziksel bellek alanı (maxRSS) değeridir. 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 takibi
Tahsis izleme, belleğin tahsis edildiği ve boşaltılmadığı yığın izlemeyi tanımlar. Bu adım, özellikle yerel kodda sızıntıları izlerken yararlıdır. Bu araç, yığın izini tanımladığından temel nedenin hızlı bir şekilde hata ayıklanması veya sorunun nasıl yeniden oluşturulacağının anlaşılması için harika bir yöntem olabilir. Ayrım izlemeyi kullanma adımları için Ayrım izleme ile yerel kodda belleği hata ayıklama başlıklı makaleye bakın.
4. adım: Uygulamanızın bellek kullanımını yığın dökümüyle 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ı olup olmadığını incelemektir. Heap 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ı tespit edebilir. Yığın dökümü aldığınızda Android Studio, hâlâ erişilebilir olan ancak zaten yok edilmiş bir etkinlik veya parça olup olmadığını kontrol eder.
- Bellek yığını dökümü yakalayın.
- Bellek sızıntılarını bulmak için yığın dökümünü analiz edin.
- Bellek sızıntılarını düzeltme.
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 Memory Profiler'ı kullanabilirsiniz.
Yığın dökümü 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.
- Bir komut istemi açın ve adb araçlarının bulunduğu dizine gidin.
Yığın dökümü almak 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 Memory Profiler'ı kullanarak bellek yığını dökümü yakalamak için Android Bellek yığını dökümü yakalama bölümündeki adımları uygulayın.
Bellek sızıntılarını bulmak için yığın dökümünü analiz etme
Bellek yığını dökümünü yakaladıktan sonra, bunu analiz etmek için Android Studio Memory Profiler'ı kullanabilirsiniz. Bunu yapmak için şu adımları uygulayın:
Android projenizi Android Studio'da açın.
Çalıştır'ı ve ardından Hata Ayıklama yapılandırmasını seçin.
Android Profiler sekmesini açın.
Anı'yı seçin.
Open heap dump'ı (Yığın dökümü aç) ve oluşturduğunuz yığın dökümü dosyasını seçin. Bellek profil oluşturucu, uygulamanızın bellek kullanımının grafiğini gösterir.
Heap dökümünü analiz etmek için grafiği kullanın:
Artık kullanılmayan nesneleri belirleyin.
Çok fazla bellek kullanan nesneleri belirleyin.
Her nesnenin ne kadar bellek kullandığını görün.
Bellek sızıntısının kaynağını daraltmak veya bulmak ve sorunu düzeltmek 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 düzeltebilirsiniz. Android uygulamalarınızdaki bellek sızıntılarını düzeltmek, 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, Android konusu Uygulamanızın belleğini yönetme bölümünde önerildiği şekilde bellek ayırdığından ve bellekten çıkardığından emin olun.
Uygulamanızdaki kullanılmayan kodları veya kaynakları kaldırın. Android uygulamalarıyla ilgili ayrıntılar için Android uygulamaları için en iyi uygulamalar başlıklı makaleyi inceleyin.
Diğer hata ayıklama araçları
Bu adımlar tamamlandıktan sonra bellek sızıntısını hâlâ bulup düzeltemediyseniz şu araçları deneyin:
- Yerel kodda bellek hatalarını ayırmak için tahsis izlemeyi kullanın.
- LeakCanary ile bellek sızıntılarını belirleyin.
Ayırma izleme ile yerel kodda bellekte hata ayıklama
Doğrudan yerel kod kullanmıyor olsanız bile Google SDK'ları dahil olmak üzere birçok yaygın Android kitaplığı yerel kod kullanır. Bellek sızıntınızın yerel kodda olduğunu düşünüyorsanız hata ayıklamak için çeşitli araçlar kullanabilirsiniz. Bellek sızıntısının olası nedenlerini belirlemek için Android Studio veya heapprofd (Perfetto ile de uyumludur) ile tahsis izleme özelliğini kullanmak harika bir yöntemdir ve genellikle hata ayıklamanın en hızlı yoludur.
Ayrıca, yığınlarda bulunabilecek hassas bilgileri dahil etmeden sonuçları paylaşmanıza olanak tanıması, tahsis izlemenin önemli bir avantajıdır.
LeakCanary ile bellek sızıntılarını tespit etme
LeakCanary, Android uygulamalarındaki bellek sızıntılarını belirlemek için kullanılan güçlü bir araçtır. LeakCanary'yi uygulamanızda kullanma hakkında daha fazla bilgi edinmek için LeakCanary sayfasını 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 çok 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 sorunu kopyalayan kodu örnek uygulamamıza kopyalamak ve sızıntıyı tetiklemek için kullanıcı arayüzünde yapılması gereken ek adımları sağlamak yardımcı 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.
Yerel bir bellek sızıntısı bekleniyorsa, heapprofd'den alınan bellek 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.