Garbage Collection (GC): nedir, algoritmalar ve mobil geliştirmede çöp toplama

Yazar: IT Sectr Yayınlanma: 2026-03-29 Okuma süresi: 10 dk

Çöp toplama yoluyla otomatik bellek yönetimi, ART sanal makinesine dayanan Android platformunun temel bir mekanizmasıdır. Google Android Documentation, 2026'ya göre, çöp toplayıcı, geliştiriciyi manuel bellek yönetiminden kurtarır ve artık referansı olmayan nesneleri otomatik olarak kaldırır. GC olmadan, her nesne tahsisi açıkça free veya delete çağrısı gerektirirdi ki bu, saniyede milyonlarca nesneyle Java ekosisteminde fiziksel olarak imkansızdır.

Önemli Noktalar

  • Garbage Collection — Java ve Android'de kullanılmayan nesneleri kaldırarak belleği otomatik olarak boşaltma mekanizması
  • Temel algoritmalar — Mark-and-Sweep, Copying Collection ve Generational Collection toplama verimliliğini belirler
  • ART ve Dalvik — Android sanal makinesinin iki uygulaması, ART (Android Runtime) Android 5.0'dan itibaren Dalvik'in yerini almıştır
  • GC Duraklamaları — toplama sırasında uygulama yürütmesinin durması — jank ve performans sorunlarının ana nedeni
  • GC Optimizasyonu — tahsisleri azaltmak, nesne havuzları kullanmak ve doğru koleksiyon türlerini seçmek toplayıcının yükünü azaltır

Garbage Collection (GC) Nedir?

Garbage Collection (GC), program tarafından artık kullanılmayan nesnelerin kapladığı belleği algılama ve boşaltma işlemidir. Mobil geliştirme bağlamında, GC, ART sanal makinesi aracılığıyla Android platformunda ve standart Java Virtual Machine'de kullanılır.

Manuel bellek yönetimine sahip dillerin (C, C++) aksine, programcının açıkça free veya delete çağırması gerekirken, GC nesne yaşam döngüsünü izleme görevini tamamen üstlenir. Geliştirici, new operatörüyle yeni nesneler oluştururken, toplayıcı bir nesnenin ne zaman ulaşılamaz hale geldiğini — yani ona hiçbir aktif referans kalmadığını belirler.

GC verimliliğinin temel metrikleri duraklama süresi (pause time) ve iş hacmidir (throughput). Duraklama, toplama işlemi için uygulama yürütmesinin durdurulduğu süredir. Mobil ortamda, 8–16 milisaniyeden uzun duraklamalar, düşen kareler (jank) olarak fark edilir.

Google I/O 2019'a göre, Android 10'daki ART, tipik GC duraklamalarını 2–4 ms'ye düşürerek Android 4.4'teki Dalvik'e kıyasla %70 azalma sağladı. Bununla birlikte, uygunsuz bellek yönetimi — döngülerde sık nesne tahsisi, gereksiz geçici örnekler oluşturma — performans sorunlarının ana nedeni olmaya devam ediyor.

Çöp Toplayıcı Nasıl Çalışır: Temel Algoritmalar

Java ve Android'deki tüm GC uygulamaları, duraklama süresi ve temizleme bütünlüğü arasında denge sağlamak için birleştirilen birkaç temel algoritmaya dayanır. Bu algoritmaları anlamak, GC dostu kod yazmak için gereklidir.

Mark-and-Sweep

Mark-and-Sweep, iki aşamada çalışan en basit algoritmadır. Mark aşamasında, toplayıcı, kök referanslardan (root set) — yerel değişkenler, statik alanlar, iş parçacığı yığınları — başlayarak nesne grafiğini dolaşır. Ulaşılabilir her nesne canlı bayrağıyla işaretlenir. Sweep aşamasında, toplayıcı tüm yığını tarar ve işaretlenmemiş nesnelerin belleğini boşaltır.

Dezavantajı bellek parçalanmasıdır: Sweep'ten sonra boş alanlar dolu alanlarla dönüşümlü olarak sıralanır ve büyük nesnelerin tahsisini zorlaştırır. Mobil senaryolarda bu kritiktir çünkü yığın genellikle küçüktür (Android'de 64–512 MB).

Copying Collection

Copying Collection, yığını iki yarı-uzaya (semi-spaces) böler. Aktif nesneler, boşluksuz olarak bir yarı-uzaydan diğerine sıkıştırılarak kopyalanır. Kopyalamadan sonra eski yarı-uzay tamamen boş ilan edilir. Algoritma, parçalanmayı tamamen ortadan kaldırır ancak iki kat daha fazla bellek gerektirir.

Mobil ortamlarda Copying Collection, istatistiksel olarak erken ölen genç nesnelerin (zayıf kuşak hipotezi) hızlı temizliği için kuşaksal toplayıcılar tarafından kullanılır.

Generational Collection

Generational Collection, yığını kuşaklara ayırır: Young Generation (genç nesneler) ve Old Generation (birkaç koleksiyondan kurtulan yaşlı nesneler). Genç kuşağın toplanması (Minor GC) sık ve hızlı yapılır çünkü çoğu nesne genç yaşta ölür. Yaşlı kuşağın toplanması (Major GC veya Full GC) daha seyrek olur ancak daha uzun sürer.

java
// Kuşaksal GC gösterimi: genç nesneler hızla ölür
void processItems(List<Item> items) {
    List<Result> results = new ArrayList<>();       // tüm metod boyunca yaşar
    for (Item item : items) {
        Result r = new Result(item.getValue());    // anında ölür
        if (r.isValid()) {
            process(r);                               // r çöp haline gelir
        }
    }
    saveResults(results);                             // results Old Gen'e geçer
}

Bu örnekte, Result nesneleri bir döngü içinde oluşturulur ve hemen çöp haline gelir — bunlar Young GC için ideal adaylardır. results nesnesi daha uzun yaşar ve Old Generation'a geçer. Kuşak ayrımı, Minor GC'nin eski yığına dokunmadan genç nesneleri milisaniyeler içinde temizlemesine olanak tanır.

Android'de Garbage Collection: ART ve Dalvik

Android, Dalvik VM'den ART'ye (Android Runtime) evrildi ve GC uygulaması aralarındaki temel farklardan biridir. Android'deki GC mimarisini anlamak, gerçek cihazlarda duraklamaları en aza indiren kod yazmaya yardımcı olur.

ÖzellikDalvik (4.4'e kadar)ART (5.0+)
GC TürüConcurrent Mark ile Mark-and-SweepGenerational + Concurrent
Tipik duraklama10–30 ms2–4 ms
SıkıştırmaHayır (sadece parçalanma artar)Evet (arka planda, uygulamayı durdurmadan)
AOT DerlemeJIT (Just-In-Time)AOT + JIT (hibrit)

Dalvik GC

Dalvik, eşzamanlı bir aşamayla Mark-and-Sweep kombinasyonunu kullandı. Concurrent Mark, nesne grafiği geçişi sırasında uygulamanın çalışmaya devam etmesine izin verirken, Sweep aşaması tüm iş parçacıklarının durdurulmasını gerektiriyordu (Stop-The-World). Az RAM'e sahip cihazlarda (512 MB — 1 GB), duraklamalar 30 ms'ye ulaştı ve arayüzde belirgin yavaşlamalara neden oldu. Ayrıca Dalvik yığını sıkıştırmadı, bu nedenle uzun süreli kullanımdan sonra parçalanma arttı ve yeterli toplam boş bellek olmasına rağmen büyük nesnelerin (örneğin, Bitmap) tahsisi OutOfMemoryError fırlatabiliyordu.

ART GC

ART (Android Runtime), eşzamanlı sıkıştırmalı kuşaksal bir toplayıcı getirdi. Yığın üç bölgeye ayrılır: Young, Mature (Old Generation'ın benzeri) ve Large Object Space (12 KB'den büyük nesneler için). Young Bölgesi toplama, çoğu durumda iş parçacıklarını durdurmadan paralel olarak gerçekleşir. Android 10+'da, Concurrent Copying tanıtıldı — sıkıştırma, Stop-The-World olmadan arka plan iş parçacığında çalışır.

ART mimarisi sayesinde tipik GC duraklamaları 2–4 ms'ye ve genç nesnelerin baskın olduğu senaryolarda 0.5–1 ms'ye düşürüldü. Bu, Android cihazların aktif bellek işlemleri sırasında bile sabit 60 FPS'yi korumasını sağladı.

Java'da Çöp Toplayıcı Türleri

Java ekosisteminde, her biri kendi performans profiline sahip birkaç GC uygulaması vardır. Android geliştirme için seçim ART ile sınırlıdır, ancak Java GC bilgisi, mobil uygulamalar için sunucu tarafı kod yazarken ve Kotlin Multiplatform ile geliştirme yaparken faydalıdır.

Serial GC

Serial GC, tam uygulama durdurmalı (Stop-The-World) tek iş parçacıklı bir toplayıcıdır. Her Mark, Sweep ve Compact işlemi tek bir iş parçacığı tarafından gerçekleştirilir. Performansı düşüktür — mobil sunucular için kullanılmaz. Yalnızca 100 MB'a kadar yığını olan küçük uygulamalar için uygundur.

Parallel GC

Parallel GC (Throughput Collector olarak da bilinir), tüm toplama aşamaları için birden çok iş parçacığı kullanır. Maksimum iş hacmine (throughput) yöneliktir — uygulama çalışma süresine göre GC'de harcanan zamanı en aza indirir. JVM'de -XX:+UseParallelGC bayrağıyla etkinleştirilir.

G1 GC

G1 (Garbage-First) GC, Java 9+'daki varsayılan toplayıcıdır. Yığın 1–32 MB'lık bölgelere ayrılır. G1, duraklama süresini tahmin eder ve belirtilen sınır (varsayılan 200 ms) içinde kalmaya çalışır. Öncelik: en fazla çöp içeren bölgeler önce temizlenir (adı buradan gelir). G1, öngörülebilir duraklamalarla büyük yığınlı sunucular (4–64 GB) için etkilidir.

java
// Hedef duraklama 100 ms ile G1 GC'yi etkinleştirme
// java -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -jar app.jar

public class MemoryMonitor {
    private static final long THRESHOLD = 512 * 1024 * 1024; // 512 MB

    public void checkHeapUsage() {
        Runtime rt = Runtime.getRuntime();
        long used = rt.totalMemory() - rt.freeMemory();
        if (used > THRESHOLD) {
            System.out.println("Heap usage exceeded threshold: " + used);
            System.out.println("Consider reducing allocations");
        }
    }
}

Runtime aracılığıyla yığını izlemek, bellek sızıntılarını erken aşamada tespit etmeyi sağlar. Kararlı çalışmada used maksimum yığının %80'ini aşarsa — bu, olası bir sızıntı veya uygulamanın aşırı bellek tüketimi sinyalidir.

GC Sorunları ve Mobil Uygulamalarda Bellek Optimizasyonu

Modern ART GC bile tüm sorunları çözmez — uygunsuz bellek kullanımı, jank ve ANR'nin (Application Not Responding) ana nedeni olmaya devam etmektedir. Ana senaryoları ve optimizasyon yöntemlerini inceleyelim.

GC Duraklamaları ve Jank

GC Duraklamaları — toplama sırasında uygulama iş parçacıklarının durmasıdır. Ekranda bu, iki kare arasındaki süre 16.6 ms'yi (60 FPS) aştığında düşen kareler olarak kendini gösterir. GC 30 ms sürerse, iki yerine yalnızca bir kare çizilir — kullanıcı arayüzde takılma görür.

Uzun duraklamaların ana nedenleri: Old Generation'da çok sayıda canlı nesne, yığın parçalanması, sık Full GC. Teşhis için Android Studio Profiler ve systrace kullanılır.

GC Yükünü Azaltma

GC dostu kodun ana kuralı, tahsis edilen nesne sayısını en aza indirmektir. Her yeni nesne yalnızca bellek tahsisi değil, aynı zamanda sonraki toplama da gerektirir. GC hızlı olsa bile, saniyede 1000 ekstra tahsis, toplayıcı için 1000 kontrol oluşturur.

  • Döngülerde nesne oluşturmaktan kaçının — oluşturmayı döngü dışına taşıyın, yerel değişkenleri yeniden kullanın
  • Nesne havuzları kullanın — Bitmap, byte[] ve diğer ağır yapılar için Object Pool veya RecyclerView.ViewHolder kullanın
  • İlkelleri tercih edin — Integer yerine int, Float yerine float autoboxing'i önler
  • SparseArray kullanın — HashMap<Integer, V> yerine, Android SDK ilkellerle çalışan SparseArray, LongSparseArray sunar
  • Birleştirme yerine StringBuilder — her dize birleştirme yeni bir String nesnesi oluşturur

Bellek Sızıntıları

Bellek sızıntısı, bir nesne artık ihtiyaç duyulmasa bile ulaşılabilir durumda kaldığında oluşur. GC böyle bir nesneyi silemez ve bellek giderek tükenir. Tipik nedenler: kaydı silinmemiş dinleyiciler, Activity'ye statik referanslar, harici bağlamı yakalayan anonim sınıflar ve kapatılmamış Cursor/InputStream.

java
// Bellek sızıntısı: anonim sınıf Activity referansını tutar
public void startTask() {
    new Thread(new Runnable() {                    // örtük olarak this (Activity) tutar
        @Override
        public void run() {
            // uzun işlem...
            System.out.println("Done");
        }
    }).start();
}

// Düzeltme: statik iç içe sınıf + WeakReference
private static class TaskRunnable implements Runnable {
    private WeakReference<Activity> activityRef;

    TaskRunnable(Activity activity) {
        this.activityRef = new WeakReference<>(activity);
    }

    @Override
    public void run() {
        Activity act = activityRef.get();
        if (act != null) {
            // Activity ile güvenli çalışma
        }
    }
}

Bu örnekte, anonim Runnable Activity'ye örtük bir referans yakalar. İş parçacığı canlı olduğu sürece — kullanıcı ekranı kapatmış olsa bile Activity GC tarafından toplanamaz. WeakReference + statik sınıf ile düzeltme bu zinciri kırar ve Activity'nin serbest bırakılmasını sağlar.

Sıkça Sorulan Sorular

Android'deki GC, Java'daki GC'den nasıl farklıdır?

Android'deki (ART) GC, sınırlı belleğe sahip mobil cihazlar için optimize edilmiş, eşzamanlı sıkıştırmalı kuşaksal bir toplayıcıdır. Java GC (G1, ZGC) büyük yığınlara ve öngörülebilir duraklamalara sahip sunucu tarafı toplayıcılardır. ART GC, JVM bayrakları kullanmaz — tüm ayarlar işletim sistemi düzeyinde otomatik olarak yapılır.

GC'de Stop-The-World nedir?

Stop-The-World, toplayıcının nesne grafiğini güvenli bir şekilde dolaşmak veya belleği boşaltmak için uygulamanın tüm iş parçacıklarını duraklattığı andır. STW ne kadar uzunsa jank o kadar belirgindir. ART, kuşaksal mimarisi sayesinde tipik STW süresini 2–4 ms'ye düşürdü.

Android'de bellek sızıntısı nasıl tespit edilir?

Android Studio Memory Profiler'ı kullanın — yığın büyümesini, tahsis sayısını gösterir ve Heap Dump almayı sağlar. Derinlemesine analiz için LeakCanary'yi kullanın — kitaplık sızıntıları otomatik olarak tespit eder ve GC toplamayı engelleyen referans zincirini gösterir.

Full GC ne zaman oluşur ve neden tehlikelidir?

Full GC, Old Generation dahil tüm yığın kuşaklarının tam bir koleksiyonudur. Mobil uygulamalarda Full GC 50–200 ms sürebilir ve belirgin jank veya ANR'ye neden olabilir. Ana nedenler: yığın parçalanması, bellek sızıntıları, Old Generation eşiğinin aşılması.

Kotlin bellek sızıntılarını önlemeye nasıl yardımcı olur?

Kotlin, yapılandırılmış eşzamanlılıkla coroutine'ler sağlar — kapsam iptali, tüm alt coroutine'leri otomatik olarak iptal ederek sızıntıları önler. Kotlin'de ayrıca geç başlatma için lazy delegesi ve geçici nesne sayısını azaltan kapsam işlevleri bulunur.

Özet

  • Garbage Collection — ulaşılamaz nesneleri kaldırarak otomatik bellek yönetimi, Android Runtime'ın temeli
  • Mark-and-Sweep — iki aşamalı toplama ile temel algoritma, yığın parçalanmasından muzdarip
  • Copying Collection — canlı nesneleri sıkıştırılmış bir yarı-uzaya kopyalayarak parçalanmayı ortadan kaldırır
  • Generational GC — yığını kuşaklara (Young/Old) ayırarak kısa ömürlü genç nesnelerin toplamasını hızlandırır
  • Android'de ART — eşzamanlı sıkıştırma ve 2–4 ms duraklamalarla kuşaksal toplayıcı, Android 5.0'da Dalvik'in yerini aldı
  • GC Optimizasyonu — tahsisleri azaltma, nesne havuzları, sarmalayıcılar yerine ilkeller ve HashMap yerine SparseArray toplayıcı yükünü azaltır
  • Teşhis — Android Studio Profiler, systrace ve LeakCanary bellek sorunlarını belirlemede ana araçlardı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