Android’de Bellek Sızıntısını Önleme

Bir çok akıllı cihaz kullanıcıları, telefon, IPad ya da Tablet şarjlarının çabuk bitmesinden şikayetçidir. Peki biz yazılım geliştiricileri olarak, cihazların minimum şarj tüketmesinde nasıl çözümler üretebiliriz?

Telefon, IPad ve Tablet cihazlarının, enerji kapasitesi düşüktür. Bu yüzden her zaman hafıza tüketimine dikkat etmeliyiz. Hafıza tüketimine sağlayan 2 nedenden bahsetmek gerekirse, 1. neden, İşletim sistemi parçalarının yeterince verimli olmadığı, 2. sebep ise cihazda var olan uygulamaları oluşturan geliştiricilerin, belleği düzgün kullanacak kodlar yazmamış olmasıdır. Bu nedenle Android veya iOS bir mobil uygulama geliştireceğiniz zaman, düşünülmesi gereken en önemli konulardan biri; “Geliştireceğim uygulamada, hafıza kullanımını nasıl yönetebilirim?” ‘dir.

Android Bellek sızıntıları oluşturmak oldukça kolaydır.Bilinçsiz geliştiriciler, her gün farkında olmadan bir miktar bellek sızdırıyor olabilir. Muhtemelen geliştiriciler henüz bu durumun farkında değil, ta ki Logcat’ de aşağıdaki gibi açıklamalar görene kadar…

Geliştiricinin aklına, “Bu log’un anlamı nedir? Acaba Android uygulamam için kullandığım bitmap resmin boyutumu yüksek geldi?” gibi sorular gelebilir.

Aslında uygulamanız OutOfMemoryError hatası verdi.OutOfMemoryError hatası aldığınızda, daha önceden yaklaşık 9 yada 10 kere bellek sızıntısı yaşadığınız anlamına gelmektedir.Yani bu log’u görene kadar zaten bir çok bellek sızıntısına maruz kaldığınızın işaretidir bu…

Bellek Sızıntısı Nedir?

Bir uygulama defalarca geçici kullanım için elde ettiği bellek dönmek için başarısız olduğunda bir bellek sızıntısı mevcut cihazda, belleği kademeli kaybıdır.

Android Yazılımda Nasıl Bir Bellek Sızıntısı Oluşur?

Android’de bellek sızıntıları oluşturmak, aslında çok kolaydır.Bellek sızıntısının oluşumuna en büyük neden, Android Contex nesnesidir ve genelde her Android uygulamada getApplicationContext() kullanılmaktadır.
Android uygulamanızda artan bellek kullanımı takip edebilmeniz için büyük bir ölçüde yardımı olan araçlar bulunmaktadır.Grafiksel olarak gösterim için, Android Memory Monitor kullanılmaktadır.

monitor1

a1- Bir uygulamada bellek sızıntısı yaşanırken Android Memory Monitor görünümü

monitor2

a2- Bellek sızıntı sabitlendikten sonraki Android Memory Monitor görünümü

a1 grafiğinde gördüğünüz üzere, bazı bellek kullanımlarını yeniden kazanmak istediğinde, uygulamanın bunu yapabilmesi mümkün olmadı. OutOfMemoryError oluşmadan önce bir noktada yaklaşık 300MB kadar bellek kullandı. a2 grafiğindeki uygulama ise , bazı bellekleri yeniden toplamak için çöp yapabiliyor ve bellek kullanımı oldukça tutarlı kalmasını göstermektedir.

Bellek Sızıntısını Nasıl Önleyebiliriz?

  • Uygulamada kullandığınız fragment veya activity’lerin içinde Context nesneleri mümkün mertebede az kullanmalısınız.
  • Hiç ama hiç birzaman, Context veya View’leri statik değişken olarak
    tanımlamayınız.Böle bir tanımlama yaparsanız, bu durum bir bellek sızıntısı ilk işaretidir.
  • Her zaman OnPause () ve OnDestroy () metodlarının dinleyici kaydını silmelisin.Bu Android dinleyiciler, örneğin konum servisleri,ekran yönetici hizmetlerinde bulunur.
  • Eğer bir activity içinde Context nesnesi kullanacaksan, Context-application (getApplicationContext()) yerine Context şeklinde tanımlayarak kullanın.
  • Eğer bellek sızıntısını önlemek istiyorsanız, non-static inner sınıflar kullanmamaya çalışın. Böle bir sınıf içinde bir Activity veya View gibi bir şey referansı saklanması bellek sızıntıları yol açabilir.Eğer bunları saklamak gerekiyorsa WeakReference kullanın.

Bellek Sızıntısını Nasıl Düzeltebiliriz?

Bellek sızıntılarının izini aramak çok zordur. Neyse ki, olası bir sızıntıyı belirlemenize yardımcı olabilecek bir kaç araç bulunmaktadır.Ben ise size, Heap Profile (hprof) dosyasını oluşturarak sızıntıyı tespit etmenizin yöntemini anlatacağım.Şimdi bu yöntemi kullanabilmek için hangi eylemleri yapmamız gerektiğinden bahsedeceğim.

  1. Testi yapmak istediğiniz projeyi Android Studio Ide’sinde açtıktan sonra Android Monitor tabı açınız.
  2. Projenizi çalıştırın.
  3. Android Monitor tabında, Memory tabını açınız.
  4. Memory tabında, memory grafiğinin çizildiğini göreceksiniz.Aşağıdaki resimde  turuncu okla  gösterdiğim, Initiate GC butonu seçin.Initiate
  5. Birkaç saniye bekledikten sonra sşağıdaki resimde kırmızı okla gösterdiğim, “Dump Java Heap” butonu seçin.Bu işlemden sonra, projenizin bellek kullanımını analiz etmek de kullanacağımız hprof dosyasını oluşturmuş olduk.Bu dosya projenin ana dizininde olan captures dosyanın içinde otomatik oluşturuldu.
  6. Android Studio’da Hprof dosyasını inceleyebilmek için bir araç bulunmamaktadır.Bu yüzden MAT programını indirmeniz gerekmektedir.
  7. -MAT programının anlayacağı şekilde bir yeni hprof dosya oluşturmamız gerekmektedir. sdk\platform-tools yolunu Git bash, komut penceresinde açın.Aşağıdaki komut örneğinden yola çıkarak yeni hprof dosyanızı oluşturun. komut
  8. Yeni oluşturduğunuz dosyayı, MAT programında File->Open Heap Dump seçerek açın ve Getting Started adlı açılan pencereden “Leak Suspects Report” seçin ve Finish tıklayın.
    leak
  9. Aşağıdaki resimde kırmızı ile işaretlediğim “Create a histogram from an arbitrary set of objects” butonunu seçiniz. Açılan sayfada listelenen objelerin bellek de kapladığı miktarları göreceksiniz.
    histogram
  10. Nesnelerin listelenmiş halini görünce biraz kafanız karışmış olabilir. Sınıf adına göre nesneleri filtreleyebilirsin.Bu yüzden sınıf adı filtresini paket adını yazarak yapmanı öneriyorum.
    filter
  11. Filtrelediğiniz sınıfların bellek sızıntısıyla alakalı bilgi edinmek için ilgili sınıfı belirleyip üzerine mouse ile sağ tıklayanız. “Merge Paths to Shortest GC Root” seçtikten sonra “exclude all phantom/weak/soft etc. references” başlığını seçiniz.merges
  12. Aşağıdaki resimde gördüğünüz üzere, kaydedilmiş display listener, kaydedilmemiş olarak metod çağrıldığı için bellek sızıntısı oluştu. finalleak

Tabiki tüm bellek sızıntılarını bulmak bu kadar kolay değildir.Bazılarını bulmak daha zor olabiliyor.Diğer bir yandan umarım bu makale potansiyel bellek sızıntıları önlemek ve bulabilmek noktasında fayda sağlar.Bellek sızıntılarını bulmak konusunda Memory Monitor haricinde kullanabileceğiniz başka araçlarda bulunmaktadır.Bu araçları Memory Profilers linkinde inceleyebilirsiniz.

Kaynaklar
1- http://riggaroo.co.za/fixing-memory-leaks-in-android-outofmemoryerror/?utm_term=0_4eb677ad19-ef86743f54-337838825&utm_content=buffer7b25e&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer

2-http://android-developers.blogspot.com.tr/2009/01/avoiding-memory-leaks.html

3-https://www.linkedin.com/pulse/fixing-memory-leaks-android-studio-albert-lai

Kategori Genel
Etiketler