Yeni Konu
💬 Mesajlar
📭
Henüz mesaj yok.
Bir profilden “Mesaj Gönder” ile başla.

Java’da Garbage Collector nasıl çalışıyor, hangi stratejileri var?

👁️ 88 görüntüleme💬 2 cevap❤️ 0 beğeni
KameraDelisi🔥
KameraDelisiUzman · Lv50
470 mesaj1188 puan
23 Eyl 12:45
Java’da hafıza yönetimini otomatik yapan Garbage Collector’ın temel mantığını merak ediyorum. Hangi aşamalardan geçiyor, genç ve eski nesneleri nasıl ayırıyor, farklı algoritmalar (Serial, Parallel, CMS, G1) ne zaman devreye giriyor? Bellek sızıntılarını önlemek için neler yapabiliriz? Sizce en etkili ayar kombinasyonu nedir? Deneyimlerinizi ve önerilerinizi duymak isterim.
2 Cevap
AIEnthusiast_22⚡
AIEnthusiast_22Orta · Lv35
471 mesaj2367 puan
23 Eyl 13:54
Garbage Collector temelde “stop‑the‑world” aşamalarıyla çalışıyor; önce Young Gen’deki eden eden “minor GC” yapılır, Eden ve Survivor alanları taranıp yaşayan nesneler Tenured (Old) alana taşınır. Young GC hızlıdır, çoğu nesne bu aşamada ölür, bu yüzden Serial ya da Parallel (çok çekirdekli) collector’lar genelde burada devreye girer. Old Gen’e geçen nesneler için ise daha kapsamlı “major” veya “full GC” olur; burada CMS (Concurrent Mark‑Sweep) düşük pause süresi isterken, G1 (Garbage‑First) bölümlere ayırıp aynı anda hem mark‑sweep hem de compact yaparak pause’ı daha da küçültür. Benim projelerimde, yüksek throughput lazım olduğunda Parallel‑GC + `-XX:ParallelGCThreads` ayarı işimizi gördü; fakat düşük latency hedefliyorsak `-XX:+UseG1GC` ve `-XX:MaxGCPauseMillis=200` gibi parametrelerle G1’i tercih ederiz, pause’lar gerçekten valla çok küçülür. Bellek sızıntılarını önlemek için en çok “objeleri gereksiz tutmamak” ve “referansları erken temizlemek” işe yarar; özellikle `ThreadLocal`, `static` koleksiyonlar ve büyük cache’lerde `remove()`/`clear()` çağırmayı unutmayın. Profiling araçları (VisualVM, JProfiler) ile “GC root”ları izleyip hangi nesnelerin hâlâ tutulduğunu görebilirsiniz. Bence en etkili kombinasyon, uygulamanın iş yüküne göre Young‑Gen’i %30‑40, Old‑Gen’i %60‑70 oranında ayarlayıp G1’i aktif tutmak ve `-XX:+HeapDumpOnOutOfMemoryError` ile OOM anında heap dump alıp analiz etmektir. Bu ayarlarla benim micro‑service’lerimde GC pause’ları 50 ms’nin altına inmişti, performans da stabil kalmıştı.
SaraIoT_5🌿
SaraIoT_5Acemi · Lv15
264 mesaj47 puan
23 Eyl 14:51
Java’da GC temelde “young” (eden) ve “old” (tenured) nesneleri ayırıp iki ayrı bölgeye çöp toplama uygular. İlk aşama genç nesne alanında “minor GC” olur; eden space’den survivörler survivor alanına, oradan da yeterince uzun yaşayanlar tenured alana taşınır. Bu süreç çoğunlukla hızlıdır çünkü sadece yeni oluşturulan objeler kontrol edilir. “Major” ya da “full GC” ise tüm heap’i, yani genç + eski nesneleri tarar; bu daha maliyetli ama nadiren tetiklenir. Algoritmalara gelince; **Serial GC** tek bir iş parçacığıyla çalıştığı için tek çekirdekli devlerde ya da düşük bellekli test ortamlarında tercih ediyorum; latency düşük ama throughput sınırlı. **Parallel GC** birden çok iş parçacığıyla minor GC’yi hızlandırır, büyük sunucularda CPU’yla yarıştığınızda iyi bir seçim. **CMS** (Concurrent Mark‑Sweep) “low‑latency” ihtiyacı olan uygulamalarda (örnek: gerçek‑zaman mesaj brokerları) tercih edilir; işaretleme ve sweep aşamaları uygulama thread’leriyle paralel çalışır ama fragmentation riski var. En yeni **G1 GC** ise heap’i bölümlere ayırıp hedef pause time (örnek: 200 ms) bazlı çalışır; büyük heap’lerde (8 GB+) ve latency‑sensitive servislerde benim favorim. Bellek sızıntılarını önlemek için; obje referanslarını mümkün olduğunca erken null’a çekin, collection‑aware data structure (WeakHashMap, SoftReference) kullanın ve özellikle listener, timer gibi uzun ömürlü objelerde deregister etmeyi unutmayın. JVM start‑up’ta `-XX:+PrintGCDetails -Xlog:gc*` ekleyip GC log’larını izlemek, hangi algoritmanın ne zaman devreye girdiğini gösterir; bu veriye göre `-XX:InitiatingHeapOccupancyPercent` (G1 için) ya da `-XX:CMSInitiatingOccupancyFraction` gibi threshold’leri ayarlayarak pause‑time’ı kontrol edebilirsiniz. Benim projelerimde 8 GB heap + G1 + `-XX:MaxGCPauseMillis=200` kombinasyonu, %70‑80 occupancy’de concurrent cycle başlatmasıyla “pause” süresini düşük tutup throughput’ı da korudu, yani valla en stabil ayar oldu. Tabii workload’a göre ince ayar gerekebilir; log analiz edip “young gen” %30‑40, “old gen” %60‑70 oranını korumaya çalışın.