Bellek yönetimi için en iyi uygulamalar

Bu dokümanda, bellek yönetimi kapsamındaki Android uygulamaları için Uygulamanızın belleğini yönetme gibi en iyi uygulama kılavuzuna uyduğunuzdan varsayılmaktadır.

Giriş

Bellek sızıntısı, bir bilgisayar programı artık ihtiyaç duyulmayan ayrılmış belleği serbest bırakmadığında meydana gelen 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. Hatalı yapılan bazı 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ı iptal edilmeyebilir.

Bu belgede, kodunuzdaki bellek sızıntılarını önlemeye, tespit etmeye ve çözmeye 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 bölümüne bakın.

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 dokümanda belirtilen hata ayıklama adımlarıyla birlikte en iyi uygulamaları izleyin. Bu adımlar sorununuzu çözebilir. Çözmezse Google destek ekibinin size yardımcı olması için gereken bilgileri üretirler.

Bellek sızıntılarını önleyin

Google SDK'larını kullanan kodlardaki bellek sızıntılarının en yaygın nedenlerinden bazılarını önlemek için bu en iyi uygulamaları izleyin.

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ırakma.
  2. Artık ihtiyaç kalmadığında işleyicilerin kaydını iptal edin.
  3. Gerekli olmadığında görevleri iptal edin.
  4. Kaynakları serbest bırakmak için yaşam döngüsü yöntemlerini iletme.
  5. SDK'ların en son sürümlerini kullanın

Bu uygulamaların her birine özel ayrıntılar için aşağıdaki bölümlere bakın.

Kullanılmayan kaynakları serbest bırakma

Android uygulamanız bir kaynak kullandığında, söz konusu kaynağı artık ihtiyaç duyulmadığında serbest bıraktığınızdan emin olun. Aksi takdirde kaynak, uygulamanız kendileriyle tamamlandıktan sonra bile bellekte yer kaplamaya devam eder. Daha fazla bilgi için Android dokümanlarındaki Etkinlik yaşam döngüsü bölümünü inceleyin.

GeoSDK'larda eski Google Map referanslarını yayınlama

Yaygın olarak yapılan bir hata, Google Map'in NavigasyonView veya MapView kullanılarak önbelleğe alınması halinde bellek sızıntısına yol açabilmesidir. Bir Google Map'in, alındığı NavigationView veya MapView ile 1'e 1 ilişkisi vardır. Bir Google Haritası'nın önbelleğe alınmadığından veya NavigationView#onDestroy veya MapView#onDestroy çağrıldığında referansın yayınlandığından emin olmanız gerekir. NavigationSupportFragment, MapSupportFragment veya bu görünümleri sarmalayan kendi parçanız kullanılıyorsa 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ı iptal et

Android uygulamanız bir düğme tıklaması veya bir görünümün durumunda değişiklik gibi bir etkinlik için işleyici kaydederse, uygulamanın etkinliği izlemesine gerek kalmadığında işleyicinin kaydını sildiğinizden emin olun. Aksi takdirde, dinleyiciler, uygulamanız kendileriyle bittikten sonra bile bellek kullanmaya devam eder.

Örneğin, uygulamanızın Navigasyon SDK'sını kullandığını ve varış etkinliklerini dinlemek için şu işleyiciyi çağırdığını varsayalım: varış etkinliklerini dinlemek için addArrivalListener yöntemini; varış etkinliklerini artık 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 eşzamansız bir görev başlattığında, tamamlandığında görevi iptal ettiğinizden emin olun. Görev iptal edilmezse uygulama tamamlanmış olsa bile arka planda çalışmaya devam eder.

En iyi uygulamalar hakkında ayrıntılı bilgi için Android dokümanlarındaki Uygulamanızın belleğini yönetme bölümüne bakın.

Kaynakları serbest bırakmak için yaşam döngüsü yöntemlerini iletme

Uygulamanız Gezinme veya Haritalar SDK'sını kullanıyorsa yaşam döngüsü yöntemlerini (kalın karakterlerle gösterilmiştir) navView platformuna ileterek kaynakları yayınladığınızdan emin olun. Bunu, Gezinme SDK'sinde NavigationView veya Haritalar ya da Navigasyon SDK'sında MapView kullanarak yapabilirsiniz. Sırasıyla 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ı sürekli olarak yeni özellikler, hata düzeltmeleri ve performans iyileştirmeleriyle güncellenmektedir. Bu düzeltmeleri almak için uygulamanızdaki SDK'ları güncel tutun.

Bellek sızıntıları için hata ayıklama

Bu dokümanın önceki bölümlerinde geçerli tüm önerileri uyguladıktan sonra da bellek sızıntılarını görmeye devam ederseniz hata ayıklamak için bu işlemi uygulayın.

Başlamadan önce Android'in belleği nasıl yönettiğini öğrenmeniz gerekir. Bilgi için Android Bellek yönetimine genel bakış bölümünü okuyun.

Bellek sızıntılarını ayıklamak için şu süreci izleyin:

  1. Sorunu yeniden oluşturun. Bu adım hata ayıklamak için çok önemlidir.
  2. Bellek kullanımının beklenip beklenmediğini kontrol edin. Sızıntı gibi görünen artan kullanımın, uygulamanızı çalıştırmak için gereken bellek miktarı olmadığından emin olun.
  3. Üst düzey hata ayıklayın. Hata ayıklamak için kullanabileceğiniz birkaç yardımcı program vardır. Android'de üç farklı standart araç seti, Android'de bellek sorunlarının giderilmesine 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 edin. Yığın dökümü ve ayırma izleme alıp analiz edin.
  5. Bellek sızıntılarını düzeltin.

Aşağıdaki bölümlerde bu adımlar ayrıntılı olarak ele alınmaktadır.

1. adım: Sorunu yeniden oluşturun

Sorunu yeniden oluşturamıyorsanız öncelikle bellek sızıntısına yol açabilecek senaryoları düşünün. Sorunun yeniden oluşturulduğunu biliyorsanız doğrudan yığın yığınına bakmak işe yarayabilir. Ancak uygulama başlatılırken yığın dökümü veya rastgele bir zamanda başka bir noktayla karşılaşırsanız sızıntıyı tetikleyecek koşulları etkinleştirmemiş olabilirsiniz. Sorunu yeniden oluşturmaya çalışırken çeşitli senaryolar üzerinde çalışabilirsiniz:

  • Hangi özellik grubu etkinleştirilir?

  • Hangi kullanıcı işlemleri sırası sızıntıyı tetikler?

    • Bu reklam dizisini etkinleştirmek için tekrar tekrar kullanmayı denediniz mi?
  • Uygulama hangi yaşam döngüsü aşamalarından geçti?

    • Farklı yaşam döngüsü durumlarında birden fazla yineleme denediniz mi?

Sorunu en son SDK sürümünde yeniden oluşturabildiğinizden emin olun. Önceki bir sürümden kaynaklanan sorun zaten düzeltilmiş olabilir.

2. Adım: Uygulamanın bellek kullanımının beklenip beklenmediğini kontrol edin

Her özellik için daha fazla bellek gerekir. Farklı senaryolarda hata ayıklarken bunun beklenen bir kullanım mı yoksa aslında bir bellek sızıntısı mı olduğunu 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ı bir sızıntı: Senaryonun birden fazla yinelemeyle 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.

  • Muhtemelen beklenen bellek kullanımı: Bellek kullanımı bir süre arttıktan sonra yavaşlar. Bunun nedeni sınırlı önbellek veya beklenen başka bellek kullanımı olabilir.

Uygulama, beklenen bellek kullanımından kaynaklanıyorsa bu sorun, uygulamanızın belleğini yöneterek çözülebilir. Yardım için Uygulamanızın belleğini yönetme konusuna bakın.

3. Adım: Üst düzeyde hata ayıklayın

Bellek sızıntısı hatalarını ayıklarken yüksek bir düzeyden başlayın ve olasılıkları daralttıktan sonra ayrıntılı inceleme yapın. Önce zaman içinde bir sızıntı olup olmadığını analiz etmek için şu üst düzey hata ayıklama araçlarından birini kullanın:

Android Studio Bellek Profil Aracı

Bu araç, tüketilen hafızanın görsel bir histogramını sunar. Yığın dökümleri ve ayırma izleme de bu arayüzden tetiklenebilir. Bu araç, varsayılan öneridir. Daha fazla bilgi için Android Studio Memory Profiler bölümüne bakın.

Perfetto Bellek Sayaçları

Perfetto, çeşitli metrikleri izleme üzerinde hassas bir kontrole sahip olmanızı sağlar ve tüm metrikleri tek bir histogramda sunar. Daha fazla bilgi için Perfetto Bellek Sayaçları bölümüne bakın.

Perfetto kullanıcı arayüzü

Android hata ayıklama köprüsü (adb) komut satırı yardımcı programları

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

  • Meminfo, belirli bir noktada ayrıntılı bellek bilgilerini görmenizi sağlar.

  • Procstatlar zaman içinde toplanan bazı önemli istatistikler sağlar.

Burada bakmanız gereken önemli bir istatistik, uygulamanın zaman içinde ihtiyaç duyduğu maksimum fiziksel bellek ayak izidir (maxRSS). MaxPSS doğru olmayabilir. Doğruluğu artırmanın bir yolu için adb shell dumpsys procstats --help –start-testing işaretine bakın.

Tahsis izleme

Ayırma izleme, belleğin ayrıldığı ve serbest bırakılmadığı yığın izlemeyi tanımlar. Bu adım özellikle yerel koddaki sızıntıları izlerken faydalıdır. Bu araç, yığın izlemeyi (stack trace) tanımladığından, temel nedende hızlı bir şekilde hata ayıklamak veya sorunu nasıl yeniden oluşturacağınızı anlamak için harika bir yöntem olabilir. Ayırma izlemeyi kullanma adımları için Ayırma izleme ile yerel kodda bellekte hata ayıklama bölümüne bakın.

4. Adım: Yığın dökümüyle 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ü almak ve ardından sızıntıları incelemektir. 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 bellek yığını dökümünü 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ü yakalayın.
  2. Bellek sızıntılarını bulmak için yığın dökümünü analiz edin.
  3. 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ü yakala

Bellek yığını dökümünü yakalamak için Android Debug Bridge (adb) veya Android Studio Memory Profiler'ı kullanabilirsiniz.

Yığın dökümü yakalamak için adb kullanma

adb kullanarak bellek yığını dökümü yakalamak için şu adımları uygulayın:

  1. Android cihazınızı bilgisayarınıza bağlayın.
  2. Bir komut istemi açın ve adb araçlarının bulunduğu dizine gidin.
  3. Bellek 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. Bellek yığını dökümünü almak için şu komutu çalıştırın:

    adb pull $PHONE_FILE_OUT $LOCAL_FILE.

Yığın dökümü yakalamak için Android Studio'yu kullanma

Android Studio Bellek Profil Aracı'nı kullanarak bir bellek yığını dökümü yakalamak için Android'in Heapdump 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 bellek yığını dökümünü yakaladıktan sonra, analiz etmek için Android Studio Memory Profiler'ı kullanabilirsiniz. Bu işlemi gerçekleştirmek için aşağıdaki adımları uygulayın:

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

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

  3. Android Profiler sekmesini açın.

  4. Bellek'i seçin.

  5. Bellek yığını dökümünü aç'ı ve oluşturduğunuz yığın dökümü dosyasını seçin. Bellek profil aracı, 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ımlayın.

    • Her bir nesnenin ne kadar bellek kullandığını görün.

  7. Bellek sızıntısının kaynağını bulmak veya kaynağını bulup 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ın düzeltilmesi uygulamalarınızın performansını ve kararlılığını iyileştirmeye yardımcı olur. Senaryoya bağlı olarak ayrıntılar değişiklik gösterir. Ancak, aşağıdaki öneriler yardımcı olabilir:

Diğer hata ayıklama araçları

Bu adımlar tamamlandıktan sonra bellek sızıntısını hâlâ bulup düzeltemediyseniz aşağıdaki araçları deneyin:

Ayırma izleme ile yerel kodda bellekte hata ayıklama

Doğrudan yerel kod kullanmasanız bile, Google SDK'ları dahil olmak üzere bazı yaygın Android kitaplıkları kullanır. Bellek sızıntınızın yerel kodda olduğunu düşünüyorsanız hata ayıklamak 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 harika bir yoludur ve genellikle hata ayıklamanın en hızlı yoludur.

Ayırma izleme, sonuçları bir yığın içinde bulunabilecek hassas bilgileri dahil etmeden paylaşabilmenizi sağlayan belirgin bir avantaj da sunar.

LeakCanary ile sızıntıları tespit etme

LeakCanary, Android uygulamalarındaki bellek sızıntılarını tespit etmek için 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ı ile 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 çoğunu sağlayarak müşteri destek ekibiyle iletişime geçin:

  • Bellek sızıntısını yeniden oluşturma adımları. Adımlar karmaşık kodlama gerektiriyorsa sorunu çoğaltan 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 yardımcı olabilir.

  • Sorun yeniden oluşturulurken uygulamanızdan yakalanan yığın dökümleri. Bellek kullanımının önemli ölçüde arttığını gösteren iki farklı zaman noktasındaki yığın dökümlerini yakalayın.

  • Yerel bellek sızıntısı bekleniyorsa heapprofd'tan ayırma izleme çıkışını paylaşın.

  • Sızıntı koşulunu yeniden oluşturmanızdan sonra alınan bir hata raporu.

  • Bellekle ilgili kilitlenmelerin yığın izleri.

    Önemli not: Yığın izlemeler, bellek sorunlarını ayıklamak için genellikle tek başına yeterli değildir. Bu nedenle, diğer bilgi biçimlerinden birini de sağladığınızdan emin olun.