Bellek sızıntısı ve şişme — nedir, nedenleri ve nasıl kaçınılır

Yazar: IT Sectr Yayınlanma: 2026-07-28 Okuma süresi: 10 dk

Bellek sızıntısı — mobil geliştirmedeki en sinsi sorunlardan biridir. Uygulamanın bellek kullanımı, işletim sistemi tarafından belirlenen sınıra ulaşana kadar istikrarlı bir şekilde büyür ve ardından OutOfMemoryError veya zorla sonlandırma gelir. Square Engineering'e göre, Android uygulamalarının yaklaşık %40'ı yalnızca profilleme yoluyla tespit edilebilen en az bir bellek sızıntısına sahiptir. Bellek büyümesinin nedenlerini ve önleme yöntemlerini inceleyelim.

Önemli Noktalar

  • GC erişilebilirliği — kök kümesinden aktif bir referans varsa nesne silinmez
  • Activity veya Context'e statik referanslar — Android'de sızıntıların en yaygın nedeni
  • LeakCanary — Android'de otomatik sızıntı tespiti için standart araç
  • WeakReference — çöp toplamayı engellememesi gereken referanslar için çözüm
  • Lifecycle-aware bileşenler — görünüm yok edildiğinde abonelikleri otomatik olarak iptal eder

Bellek sızıntısı ve uygulama şişmesi nedir?

Bellek sızıntısı — uygulama tarafından artık ihtiyaç duyulmayan bir nesnenin, GC Kök kümesinden aktif bir referans hala onu işaret ettiği için yığında tutulmaya devam etmesi durumudur. Çöp toplayıcı böyle bir nesneyi canlı olarak kabul eder ve kaldırmaz.

Bellek şişmesi — uygulamanın mevcut görevlerini gerçekleştirmek için gerekenden daha fazla bellek tüketmesiyle ilgili daha geniş bir sorundur. Nedenleri: aşırı önbellekleme, nesne kopyalama, optimal olmayan veri yapıları ve yığın parçalanması.

Android'de her uygulamaya sınırlı bir yığın ayrılır (genellikle cihaza ve işletim sistemi sürümüne bağlı olarak 64–512 MB). iOS'ta sınır daha az katıdır, ancak sınıra yaklaşıldığında sistem bir bellek uyarısı gönderir.

ÖzellikAndroidiOS
Yığın sınırı64–512 MB (cihaza bağlı)Örtük (sistem)
Çöp toplamaART (Eşzamanlı, Kompakt)ARC (Otomatik Referans Sayma)
Sızıntı mekanizmasıGC Kök referanslarıTutma döngüleri (güçlü referans döngüleri)
SonuçOutOfMemoryErrorBellek uyarısı → sonlandırma

Facebook Engineering Blog'a göre, bellek sızıntıları mobil uygulamalardaki crash raporlarının ~%15'ine neden olur. Android'de, bellek azaldığında sık GC duraklamaları nedeniyle ANR'ler eklenir.

Android ve iOS'ta yaygın bellek sızıntısı kalıpları

Activity'ye statik referans — klasik bir Android sızıntısı. Statik bir alan veya singleton bir Activity'ye referans tutarsa, singleton canlı olduğu sürece finish()'ten sonra bile GC tarafından toplanmaz. Activity, görünüm hiyerarşisi, kaynaklar ve Context içeren ağır bir nesnedir.

kotlin
object LeakHolder {
    var activityRef: Activity ?= null // leak: static reference to Activity
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle ?= null) {
        super.onCreate(savedInstanceState)
        LeakHolder.activityRef = this // ❌ MainActivity will never be GC'd
    }
}

Anonim sınıflar ve lambdalar — dış sınıfa örtük olarak bir referans tutar. Bir Runnable veya Callback harici bir servise aktarılırsa ve Activity yok edilirse, anonim sınıf nesnesi hala kuyruktadır ve Activity'nin çöp toplamasını engeller.

  • Handler gecikmeli — Activity yok edilirse ancak Handler.postDelayed henüz yürütülmemişse, Activity sızdırılır
  • Thread ve AsyncTask — ekran döndürüldüğünde Activity yeniden oluşturulurken eski Thread eski Activity'ye referans tutmaya devam eder
  • Retrofit/Callback — anonim bir Callback, sunumcuya veya fragmana referans tutar
  • Gözlemciler — onDestroy'de abonelik iptali olmadan LiveData veya RxJava abonelikleri

iOS'ta temel sorun tutma döngüleridir: iki nesne birbirine güçlü referanslar tutar ve ARC, hiçbiri için referans sayacını sıfırlayamaz. Tipik bir durum: self'i güçlü bir şekilde yakalayan bir closure ve closure'a referans tutan self.

Bellek sızıntıları nasıl tespit edilir?

LeakCanary — Android'de otomatik sızıntı tespiti için Square'den bir kütüphane. Bir Activity veya Fragment yok edildikten sonra, nesnenin GC tarafından toplanıp toplanmadığını kontrol eder. Toplanmadıysa, bir yığın dökümü alır ve sızıntı izini gösterir.

kotlin
// LeakCanary 2.x — auto-integration via Application
class ExampleApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        // LeakCanary auto-installs in debug build
        // via ContentProvider — zero code setup
    }
}

// Force check invocation
AppWatcher.objectWatcher.watch(watchedObject, "leak description")

Android Studio Profiler — gerçek zamanlı bellek izleme için yerleşik bir araçtır. Yığın dökümü kaydetmeye, şüpheli nesneleri (Retained Size > 1 MB) bulmaya ve her nesneye GC kök yolunu izlemeye olanak tanır.

iOS için Xcode Memory Graph Debugger'ı kullanın. Bellekteki nesne grafiğini görselleştirir, tutma döngülerini gösterir ve dairesel referansları anında tespit etmenizi sağlar. Uzun vadeli izleme için Instruments > Allocations da mevcuttur.

Önleme stratejileri

WeakReference — çöp toplamayı engellememesi gereken referanslar için temel bir mekanizmadır. GC bir nesneyi toplamaya karar verirse, WeakReference null döndürür. Geri aramalar, dinleyiciler ve arka plan iş parçacıklarından UI bileşenlerine yapılan referanslar için kullanılır.

Lifecycle-aware bileşenler — Android Jetpack'te (Lifecycle, LiveData, Flow, coroutines) uygulanan mimari bir yaklaşımdır. Abonelikler onDestroy'de otomatik olarak iptal edilir ve ana sızıntı sınıfını ortadan kaldırır.

kotlin
class MyViewModel : ViewModel() {
    private val _data = MutableLiveData<List<User>>()
    val data: LiveData<List<User>> get() = _data

    fun loadData() {
        viewModelScope.launch {
            val result = repository.fetchData()
            _data.postValue(result)
            // coroutine auto-cancels on onCleared()
        }
    }
}

viewModelScope ve lifecycleScope — Android'de yerleşik CoroutineScope'lardır ve ilgili yaşam döngüsü olayında iptal edilir. Bu, modern Android geliştirmede en yaygın senaryo olan coroutine'ler aracılığıyla sızıntıları ortadan kaldırır.

  • Kullanmayın Context, Activity, View veya Fragment'e statik referanslar
  • İptal edin onDestroy'de disposeBag / CompositeDisposable içindeki tüm RxJava aboneliklerini
  • Kullanın iOS closure'larında tutma döngülerini önlemek için [weak self] / [unowned self]
  • Kontrol edin Bitmap ve büyük nesneler — geri dönüştürülmeli veya null yapılmalıdır

Bellek profilleme araçları

Android Studio'daki Memory Profiler — yığın izleme için birincil araçtır. Canlı ayırmaları, yığın anlık görüntülerini ve türe göre nesne sayımlarını gösterir. Bir döküm kaydetmeye ve şüpheli nesneleri bulmak için MAT (Memory Analyzer Tool) ile analiz etmeye olanak tanır.

Eclipse MAT — bir masaüstü yığın dökümü analizörüdür. Android Studio'dan bir HPROF dosyası yükledikten sonra MAT, bir dominator ağacı oluşturur, her nesnenin tutma boyutunu gösterir ve Leak Suspects Report aracılığıyla otomatik şüpheli sızıntı analizi sunar.

Xcode Memory Graph — görsel bir tutma döngüsü hata ayıklayıcısıdır. Memory Graph Debugger düğmesine tıklandığında, Xcode uygulamayı durdurur, bellekte tam bir nesne grafiği oluşturur ve tutma döngülerini kırmızıyla vurgular.

AraçPlatformÖzellik
LeakCanaryAndroidYok etme sonrası otomatik sızıntı tespiti
Memory ProfilerAndroid StudioYığın dökümü + canlı ayırmalar
Eclipse MATAndroidDominator ağacı, Leak Suspects Report
Memory GraphiOS (Xcode)Tutma döngüsü görselleştirici

Google I/O 2023'e göre, hata ayıklama yapılarında LeakCanary kullanan uygulamalar, benimsemeden sonraki ilk 2 ayda bellek ile ilgili crash'leri %30–50 oranında azaltır. Proje onboarding aşamasında LeakCanary eklenmesi önerilir.

Sıkça Sorulan Sorular

Bellek sızıntısının şişmeden farkı nedir?

Sızıntı — koda erişilemeyen ancak aktif referanslar nedeniyle GC tarafından toplanmayan nesneler. Şişme — uygulamanın mantıksal olarak gerekli ancak aşırı miktarda nesne tutması (örneğin, 80 MB çalışan bir uygulamada 50 MB önbellek). Şişme mimari olarak, sızıntı ise doğru referans yönetimiyle çözülür.

LeakCanary sızıntıları nasıl bulur?

LeakCanary ObjectWatcher kullanır — bir Activity'nin onDestroy()'inden sonra Activity üzerinde bir WeakReference oluşturur ve GC'yi çalıştırır. 5 saniye sonra WeakReference temizlenmezse, LeakCanary bir yığın dökümü alır, GC Root'tan nesneye en kısa referans zincirini analiz eder ve dosya ve kod satırıyla birlikte tam sızıntı yığınını gösterir.

Bitmap neden sık sık OutOfMemoryError'a neden olur?

Bitmap, Java yığınının dışında yerel bellekte (native heap) yer kaplar. Bir Bitmap'in boyutu = genişlik × yükseklik × 4 bayt (ARGB_8888). 12 MP'lik bir fotoğraf (4000×3000) 48 MB yer kaplar. Android her zaman yerel belleği zamanında boşaltamaz, bu nedenle birden fazla Bitmap birikmesi, yeterli Java yığını olsa bile OOM'ye yol açar.

iOS'ta tutma döngüsü nedir?

Tutma döngüsü — ARC'de iki nesnenin birbirine güçlü referanslar tuttuğu ve referans sayacının asla sıfıra ulaşmadığı bir durumdur. Tipik bir örnek: bir closure'a güçlü referansı olan bir ViewController ve self'i güçlü bir şekilde yakalayan closure. Çözüm: closure'larda [weak self] veya [unowned self] kullanın.

Android'de maksimum yığın boyutu nedir?

Yığın boyutu cihaza ve Android sürümüne bağlıdır. Eski cihazlar (API 15–24) için — 64–128 MB. Modern cihazlar (API 25+) için — 256–512 MB. Kesin değer ActivityManager.getMemoryClass() ile alınabilir. Büyük uygulamalar (oyunlar, düzenleyiciler) için manifest'te largeHeap=true, 1 GB'a kadar sağlar.

Özet

  • Bellek sızıntısı — kök kümesinden aktif referans nedeniyle GC tarafından toplanmayan nesne; şişme — belirgin sızıntı olmadan aşırı bellek tüketimi
  • Activity, Context veya View'e statik referanslar — Android'de sızıntıların bir numaralı nedeni; çözüm — WeakReference veya Application Context
  • Anonim sınıflar ve lambdalar dış sınıfa örtük referans tutar; iptal edilmemiş geri aramalar ikinci en yaygın nedendir
  • LeakCanary — Android'de otomatik sızıntı tespiti standardı; entegrasyon 5 dakika sürer ve crash oranını %30–50 azaltır
  • lifecycleScope ve viewModelScope yok etmede coroutine'leri otomatik olarak iptal eder, tüm bir sızıntı sınıfını ortadan kaldırır
  • iOS'ta tutma döngüleri closure'larda ve delegate'lerde weak/unowned self ile çözülür
  • Belleği profilleme — sprint başına en az bir kez, MAT veya Memory Graph ile yığın dökümü kod incelemesinin bir parçası olmalıdır

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun