Bellek yönetimi için en iyi uygulamalar

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. Bir sızıntı, uygulamanın işletim sisteminden mevcut olandan daha fazla bellek istemesine ve dolayısıyla uygulamanın kilitlenmesine neden olabilir. Bazı yanlış uygulamalar, Android uygulamalarında bellek sızıntılarına neden olabilir. Örneğin, kaynakların doğru şekilde atılmaması veya artık ihtiyaç duyulmadığında dinleyicilerin kaydının iptal edilmemesi gibi.

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ı durumunu Google Destek Ekibi'ne bildirmeden önce, hatanın kodunuzda olmadığından emin olmak için bu dokümanda sağlanan hata ayıklama adımlarıyla birlikte en iyi uygulamaları takip edin. 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 bellek sızıntılarının en yaygın nedenlerinden bazılarını önlemenize yardımcı olması için bu en iyi uygulamaları takip edin.

Android uygulamaları için en iyi uygulamalar

Android uygulamanızda aşağıdakilerin tümünü yaptığınızdan emin olun:

  1. Kullanılmayan kaynakları serbest bırakın.
  2. Artık ihtiyaç duyulmadığında dinleyicilerin kaydını iptal edin.
  3. Gerekmediğinde görevleri iptal edin.
  4. Kaynakları serbest bırakmak için yaşam döngüsü yöntemlerini iletin.
  5. 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, kaynak, uygulamanız bu kaynakları kullanmayı bıraktıktan sonra bile bellek kullanmaya devam eder. Daha fazla bilgi için Android belgelerindeki Etkinlik yaşam döngüsü'nü inceleyin.

GeoSDK'larda eski GoogleMap referanslarını yayınlayın

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 Google haritasının önbelleğe alınmadığından ya da 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ç olmadığında dinleyicilerin kaydını iptal edin

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ız kendileriyle bitirildikten 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 kullanarak 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 işler.

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. Daha fazla bilgi için Android Bellek yönetimine genel bakış sayfasını okuyun.

Bellek sızıntılarını ayıklamak için aşağıdaki işlemi uygulayın:

  1. Sorunu yeniden oluşturun. Bu adım, hata ayıklamak için elzemdir.
  2. Bellek kullanımının beklenen düzeyde 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ığından emin olun.
  3. Yüksek düzeyde hata ayıklama. Hata ayıklama için kullanabileceğiniz çeşitli yardımcı programlar vardır. Android'deki üç farklı standart araç seti, Android'de bellek sorunlarında hata ayıklamaya yardımcı olur: Android Studio, Perfetto ve Android Debug Bridge (adb) komut satırı yardımcı programları.
  4. Uygulamanızın bellek kullanımını kontrol etme. Bir yığın dökümü ve tahsis izlemesi alın ve ardından bunları analiz edin.
  5. Bellek sızıntılarını düzeltme.

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ştirmek için birden fazla iterasyon 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:

  • Olası sızıntı: Senaryonun birden fazla iterasyon ile etkinleştirilmesi, zaman içinde bellek kullanımında artışa 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ını ayıklarken yüksek bir düzeyden başlayın ve ardından 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 Memory Profiler

Bu araç, kullanılan belleğin görsel bir histogramini sunar. 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.

Perfetto kullanıcı arayüzü

Android Debug Bridge (adb) komut satırı yardımcı programları

Perfetto ile izleyebileceğiniz verilerin çoğu, doğrudan sorgulayabileceğiniz bir adbkomut satırı yardımcı programı olarak da kullanılabilir. Birkaç önemli örnek verelim:

  • Meminfo, belirli bir zamandaki ayrıntılı bellek bilgilerini görmenize olanak tanır.

  • Procstats, zaman içinde bazı önemli toplu istatistikleri sunar.

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ılarını tespit etmenin bir yolu, uygulamanızın yığın dökümünü alıp sızıntı olup olmadığını 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. Yığın dökümü yakaladığınızda Android Studio, hâlâ erişilebilir ancak önceden kaldırılmış bir etkinlik veya parça olup olmadığını kontrol eder.

  1. Bellek yığını dökümü alın.
  2. Bellek sızıntısı bulmak için yığın dökümünü analiz edin.
  3. Bellek sızıntılarını düzeltme.

Ayrıntılar için aşağıdaki bölümleri inceleyin.

Yığın dökümü yakalama

Yığın dökümünü yakalamak için Android Debug Bridge (adb) veya Android Studio Memory Profiler'ı 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:

  1. Android cihazınızı bilgisayarınıza bağlayın.
  2. Komut istemi açın ve adb araçlarının bulunduğu dizine gidin.
  3. 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

  4. 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ılarını 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:

  1. Android Studio'da Android projenizi açın.

  2. Çalıştır'ı, ardından Hata ayıklama yapılandırmasını seçin.

  3. Android Profilleyici sekmesini açın.

  4. Hafıza'yı seçin.

  5. 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.

  6. 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 tanımlamak.

    • Her nesnenin ne kadar bellek kullandığını görebilirsiniz.

  7. 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 bunu 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:

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:

Ayırma izlemeyle yerel kodda bellek hatalarını ayıklama

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 hata ayıklama 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 kopyalamak ve sızıntıyı tetiklemek için kullanıcı arayüzünde uygulanması gereken ek adımları sağlamak 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.