Java'da Garbage Collection nasıl çalışır? G1 ve ZGC arasındaki farklar nelerdir, hangisini ne zaman seçersiniz?
Cevap
GC, GC root'lardan (thread stack'leri, statik alanlar, JNI referansları) ulaşılamayan nesneleri bulup belleği geri kazanır. Çoğu collector generational hipoteze dayanır: nesnelerin çoğu kısa ömürlüdür, bu yüzden young generation sık ve ucuz, old generation seyrek temizlenir.
Temel aşamalar
- Mark: root'lardan erişilebilen nesneler işaretlenir.
- Sweep / Compact: işaretsizler silinir; parçalanmayı önlemek için canlı nesneler taşınır.
- Young GC'de Eden'de hayatta kalanlar Survivor'a, birkaç döngü yaşayanlar old generation'a terfi eder (promotion).
Stop-the-world (STW) pause'lar uygulama thread'lerini durdurur; modern collector'ların amacı bu süreyi kısaltmaktır.
Collector karşılaştırması
| Collector | Özellik | Uygun senaryo |
|---|---|---|
| Serial | Tek thread, basit | Küçük heap, tek CPU, CLI araçları |
| Parallel | Throughput odaklı, STW | Batch işler, gecikme önemsiz |
| G1 (Java 9+ varsayılan) | Heap'i region'lara böler, hedef pause süresi (MaxGCPauseMillis, varsayılan 200ms) | Çoğu web servisi, 4-32 GB heap |
| ZGC | Neredeyse tüm işi concurrent yapar, pause genelde 1ms altında, TB'larca heap | Düşük gecikme kritik API'ler, büyük heap |
| Shenandoah | ZGC'ye benzer concurrent compaction | Düşük gecikme (Red Hat dağıtımları) |
Java 21'de Generational ZGC geldi (-XX:+UseZGC -XX:+ZGenerational), Java 23'te varsayılan ZGC modu oldu. Bu, ZGC'nin throughput dezavantajını büyük ölçüde azalttı.
Pratikte nasıl karar verilir?
- Önce varsayılan G1 ile başlayın, GC loglarını açın:
-Xlog:gc*:file=gc.log. - p99 gecikmede GC pause'ları görüyorsanız ve heap büyükse ZGC'yi deneyin.
- GC sorunlarının çoğu collector değil allocation sorunudur: gereksiz nesne üretimi, büyük cache'ler. Önce profiling yapın (JFR, async-profiler).
İlgili Java & Spring soruları
- Java 21 virtual thread'ler nedir? Platform thread'lerden farkı nedir ve hangi durumlarda dikkatli olmak gerekir?
- ExecutorService ve CompletableFuture ile asenkron iş nasıl yapılır? Thread pool boyutunu nasıl belirlersiniz?
- JPA/Hibernate'te lazy ve eager loading farkı nedir? LazyInitializationException neden oluşur ve nasıl çözülür?
- @Transactional anotasyonu hangi durumlarda çalışmaz? Self-invocation, rollback kuralları ve propagation tuzaklarını açıklayın.
- Spring bean scope'ları nelerdir? Singleton bir bean'e prototype bean inject edilirse ne olur?
- Spring'de Dependency Injection nedir? Constructor injection neden field injection'a tercih edilir?
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.