Nisa Efendioğlu

Android’de Memory Leak Nedir? LeakCanary ile Memory Leak Sorunlarını Tespit Etme

Profile picture

Nisa Efendioğlu

Post Image

📱 Android’de Memory Leak Nedir? LeakCanary ile Memory Leak Sorunlarını Tespit Etme

Bir Android uygulaması çalışırken, bellekte (RAM) birçok nesne oluşturulur. Bu nesnelerin yaşam süreleri uygulama akışına bağlıdır. Ancak bazı durumlarda artık gerekli olmayan nesneler arka planda yaşamaya devam eder ve Garbage Collector tarafından silinemez. İşte bu duruma Memory Leak (Bellek Sızıntısı) denir.

Memory Leak, bellek kullanımının doğru yönetilememesi sonucu oluşan ve uygulamanın performansını olumsuz etkileyen bir sorundur. Uzun vadede bu durum:

  • Bellek tüketimini artırır
  • Uygulama yavaşlamalarına sebep olur
  • OutOfMemoryError (OOM) hatalarına yol açabilir

📌 Neden Android’de Memory Leak Oluşur?

Android uygulamalarının mimarisi ve yaşam döngüleri bellek sızıntılarına eğilimlidir. Aşağıda başlıca nedenler yer almaktadır:

1. Yanlış Lifecycle Yönetimi

Android bileşenleri (Activity, Fragment, View vb.) yaşam döngülerine sahiptir. Özellikle Fragment’larda view lifecycle ile fragment lifecycle’ının karışması bellek sızıntılarına yol açar.

2. Sürekli Yaşayan Referanslar

Bir nesne bir başka nesneyi aktif bir şekilde referans tuttuğunda, GC o nesneyi temizleyemez. Özellikle:

  • Statik değişkenlerde tutulan Context
  • Uzun süreli listener’lar
  • Uygulama genelinde yaşayan callback’ler

gibi durumlar bellek sızıntısına neden olur.

3. Yanlış Yapılandırılmış Asenkron İşlemler

AsyncTask, Coroutine, Handler, Timer gibi asenkron işlemler bileşen yaşam döngüsüyle uyumlu değilse çekirdek (heap) üzerinde gereksiz nesneler birikir.

4. Büyük Veri Yapıları ve Kaynak Yönetimi

Büyük listeler, bitmap’ler veya medya nesneleri yönetilmeden belleğe yüklendiğinde, uygulama uzun süreli nesnelerle çalışıyor gibi davranır.

📌 Android’de Memory Leak Kaynakları

1. Context Leak

Android’de Context, önemli bir nesnedir. Yanlış kullanımı memory leak’e neden olabilir.

Yanlış Örnek

image

Bu kodda Activity’nin context’i singleton’a atanırsa, Activity hiçbir zaman GC tarafından temizlenemez.

Doğru Yaklaşım

image

veya

image

2. Uzun Süreli Listener / Observer

Özellikle LiveData veya custom listener’lar yanlış scope ile kullanıldığında leak’e yol açabilir.

Yanlış Örnek

image

Bu kullanım fragment kapanınca bile observer’ın yaşamaya devam etmesine neden olabilir.

Doğru Kullanım

image

3. Coroutine / Handler / Timer Kaynaklı Leak

Asenkron işlemler yaşam döngüsüne uygun bağlanmazsa leak oluşturabilir:

image

Bu kullanımda delay bitene kadar fragment yaşamaya devam edebilir.

Çözüm

image

veya

image

📌 Memory Leak Nasıl Tespit Edilir?

Android tarafında memory leak tespit etmek için birkaç güçlü araç vardır:

🔍 1. LeakCanary

LeakCanary, Android projelerine kolay entegre edilen, otomatik leak tespit ve raporlama sağlayan bir kütüphanedir. Ekstra konfigürasyon gerektirmez, ekledikten sonra otomatik çalışır.

Aşağıdaki adımları sırayla uygulayalım. 🌸

✅ 1. Adım — Gradle Dosyasını Aç

Uygulamanın app-level Gradle dosyasını aç:

  • app/build.gradle
    veya
  • app/build.gradle.kts

⚠️ Proje-level değil, app-level dosya olmalı.

✅ 2. Adım — Dependency Ekle

image

❗️Neden debugImplementation?

  • LeakCanary sadece debug build’te çalışsın diye
  • Release APK’ya girmesin
  • Kullanıcıya asla yansımasın

Bu satırı ekledikten sonra Sync Now yap.

✅ 3. Adım — Başka Bir Şeye Gerek Yok 👀

  • ❌ Application class yazmana gerek yok
  • ❌ Init çağırmana gerek yok
  • ❌ Manuel start/stop yok

LeakCanary:

  • Uygulama ayağa kalktığında otomatik başlar
  • Activity / Fragment lifecycle’larını kendisi izler

✅ 4. Adım — Leak Nasıl Yakalanır?

LeakCanary şu nesneleri otomatik izler:

  • Activity
  • Fragment
  • ViewModel
  • View
  • Service

Senaryoyu düşünelim:

👾 Bir Fragment açtın

👾 Geri bastın → Fragment destroy oldu

👾 GC çalıştı

☠️ Ama Fragment hâlâ bellekteyse...

➡️ LeakCanary “leak olabilir” der.

✅ 5. Adım — Leak Bildirimi Nerede Görünür?

Leak tespit edildiğinde:

  • Android cihazda notification (bildirim) çıkar
  • Bildirim başlığı genelde şöyle olur: “LeakCanary detected a leak”

Bildirime tıklayınca:

  • LeakCanary’nin kendi ekranı açılır
  • Leak detaylarını gösterir

✅ 6. Adım — Leak Ekranını Nasıl Okursun?

LeakCanary ekranında üç kritik alan vardır:

🔴 Leaking Object

Bellekten düşmeyen asıl nesne Örn:

  • HomeFragment
  • MainActivity

🟠 Retained Size

Bu leak yüzünden bellekte tutulan yaklaşık RAM miktarı

🔗 Reference Path

Bu nesneyi hangi referans zincirinin tuttuğu

Örnek zincir:

MyAdapter
 ↓
onClickListener
 ↓
Fragment

Bu şu demek:

Adapter → listener → Fragment referansı kopmadığı için Fragment hâlâ yaşıyor.

🛠️ 7. Adım — İlk Test (Kurulum Doğru mu?)

Kurulumun çalıştığını anlamak için basit test:

👀 Fragment aç

👀 Geri çık

👀 Aynı Fragment’a 3–4 kez gir-çık yap

👀 Bekle (GC çalışsın)

Eğer:

  • Notification gelirse → leak var
  • Hiçbir şey gelmezse → şimdilik temiz

📈 Örnek Leak Raporu

image

LeakCanary Ne Zaman Kullanılmalı?

  • Feature geliştirirken
  • Yeni Fragment / Adapter yazarken
  • RecyclerView + büyük listeler varken
  • Image loader (Glide) kullanılan ekranlarda
  • QA testlerinde

LeakCanary Özellikleri:

  • Activity, Fragment gibi nesnelerin GC sonrası hâlâ yaşıyorsa rapor oluşturur
  • Bellek sızıntısı kaynağını stack trace ile gösterir
  • Debug build’lerinde otomatik olarak aktiftir

LeakCanary sayesinde hangi nesnenin neden temizlenmediğini kolayca tespit edebilirsin.

📊 2. Android Studio Memory Profiler

Android Studio içinde yer alan Profiling araçlarıyla:

  • Heap dump alabilir
  • Nesne yaşam sürelerini inceleyebilir
  • GC çağrılarını takip edebilirsin

Profiler, özellikle büyük veri işlemleri ve bellek yoğun ekranlarda son derece faydalıdır.

📌 Memory Leak Oluşmasını Önlemek İçin İpuçları

Aşağıdaki pratik uygulamalar, bellek sızıntılarını önemli ölçüde azaltacaktır:

✔ Activity / Fragment Lifecycle’a Dikkat Et

  • ViewBinding kullanıyorsan onDestroyView’da null yap
  • Fragment’ta observer’ları lifecycle owner ile bağla

✔ Context Kullanımına Dikkat Et

  • Statik alanlarda Activity context’ini saklama
  • Mümkünse applicationContext veya WeakReference kullan

✔ Asenkron İşlemleri Lifecycle’a Bağla

  • Coroutine, Handler, Timer gibi işlemleri fragment/activity lifecycle’ına bağla
  • Gereksiz uzun süreli işlemleri iptal et

✔ Büyük Kaynakları Serbest Bırak

  • Bitmap veya büyük veri objelerini gerektiğinde serbest bırak
  • RecyclerView adapter’larında gereksiz referans tutma

📌 Daha Detaylı Bellek Yapıları İçin

Bu yazıda ana odak memory leak nedir ve nasıl önlenir idi. Android bellek mimarisi (Stack vs Heap) ve Value / Reference gibi temel konuların modern JVM temelli işlendiği, çok daha detaylı anlatım için blogumdaki bu yazıya bakabilirsin:

👉 Android Heap, Stack, Value ve Reference Types — Detaylı İnceleme

📌 Sonuç

Android’de memory leak, uygulanmayan lifecycle yönetimi, yanlış referans kullanımı ve uzun süre yaşayan asenkron işlemler nedeniyle oluşur. Doğru araçlarla (LeakCanary, Profiler) tespit edip, lifecycle odaklı bir mimari ile çözümler üretmek, uygulamanın stabil ve performanslı kalmasını sağlar.

Keyifli kodlamalar!

Go back