Garbage Collection
Java’da garbage collection (GC / çöp toplama), programın dinamik belleğinde kullanılmayan nesnelerin otomatik olarak temizleyen, bu sayede de bellekte boş yer açılmasını sağlayan ve bellek sızıntılarını önleyen işlemdir. Bu yazıda, garbage collection’ın işleyişini, bellek sızıntısı risklerini ve performans optimizasyonlarını ele aldım. Konular ilişikteki projeyle birlikte ele alınmaktadır.
Garbage Collection
Java’da garbage collection, programın dinamik belleğinde kullanılmayan nesnelerin otomatik olarak temizlenmesi işlemidir. Bu sayede bellekte boş yer açılır ve bellek sızıntısı (memory leaks) önlenir. “Çöp” terimi, dizin tarafından ihtiyaç duyulmayan ancak yine de dizin üzerinde yer kaplayan tüm verileri ifade eder. Java SE (Standart Edition), uygulamanın çalıştırılacağı bilgisayarın sınıfına göre en uygun çöp toplayıcıyı seçer (garbage collector). Java, GC mekanizmasını JVM (Java Virtual Machine / Java Sanal Makinesi) aracılığıyla yönetir ve bu işlem genellikle arkada çalışan bir iş parçacığı (thread) tarafından gerçekleştirilir.
Bir çöp toplayıcısı, aşağıdaki işlemler aracılığıyla otomatik dinamik bellek yönetimi gerçekleştirir:
- İşletim sisteminden bellek ayırır ve işletim sistemine geri verir.
- Bu belleği, talep ettiği anda uygulamaya dağıtır.
- Bu belleğin hangi bölümlerinin uygulama tarafından hâlâ kullanıldığını belirler.
- Kullanılmayan belleği uygulama tarafından yeniden kullanılmak üzere geri alır.
İlgili proje üzerinden bir örneğine bakmak için sipariş iş sınıflarından OrderProcessor sınıfına bir göz atacak olursak:
Bu kod parçasında OrderProcessor sınıfının run metodunda order nesnesi işlenip ve işlem tamamlandıktan sonra bu nesne kullanılmadığında GC tarafından temizlenebilir. Nesnenin referansını null yapmak, Garbage Collector'un bu nesneyi erişilemez hale getirmesine yardımcı olabilir. Ancak GC’nin kesin çalışmasını garanti etmez; JVM'nin bellek yönetim politikalarına bağlıdır. Bu sınıfta GC mekanizmasını desteklemek için order nesnesi temizlenebilecek hale getirilebilir:
order.setStatus("Completed");
System.out.println("Order " + order.getOrderId() + " processed successfully!");
this.order = null; // Nesne referansını null yaparak garbage collector'a yardımcı olun
Ayrıca, her iş parçacığının sonlandırıldığından emin olmak da bellek yönetimi açısından önemlidir. Bu yüzden ExecutorService kullanarak thread yönetimini düzenli bir şekilde yapmak ve tüm iş parçacıkları tamamlandığında shutdown() metodunu çağırmak önemlidir. Bunun bir örneği OrderManager iş sınıfında bulunmaktadır:
Bellek Sızıntısı (Memory Leaks)
Bellek sızıntısı, programın bellekteki nesneleri serbest bırakmaması ve bu nesnelerin kullanılmamasına rağmen bellek tüketimine devam etmesi durumudur. Java’da memory leaks genellikle statik değişkenler veya yanlış kullanılan koleksiyonlar nedeniyle ortaya çıkar.
İlişik projenin OrderManager sınıfında buna da bir örnek gösterilebilir:
Bu kod parçasında orders listesindeki Order nesneleri işlenirken, kullanılmayan Order nesnelerinin bellekten kaldırıldığından emin olunmalıdır.
Performance Tuning
Java’da performans ayarlamaları yapmak, uygulamanın daha hızlı ve verimli çalışmasını sağlamak için çeşitli optimizasyon teknikleri kullanmaktır. Bu optimizasyonlar, bellek yönetimi, veri yapıları ve algoritmalar gibi konuları içerebilir. ProductManager iş sınıfında sortByPrice() yöntemini inceleyelim:
Bu kod parçasında sortByPrice metodunda paralel akış (parallel stream) kullanılarak ürünlerin fiyatına göre sıralanması sağlanır. Bu, özellikle büyük veri kümeleri için sıralama işlemini hızlandırabilir.
Nasıl Yapmalı?
GC Mekanizması İçin
Bu bölümde garbage collection mekanizmasının daha verimli işleyebilmesi için kodumuzda yapılabileceklere değinilmiştir.
Zayıf Referanslar (Weak References)
Zayıf referanslar, nesnelerin garbage collector tarafından daha hızlı temizlenmesini sağlar ve bellek sızıntılarını azaltmada yardımcı olabilirler. WeakReference sınıfı kullanılarak oluşturulurlar.
import java.lang.ref.WeakReference; cache =
public class Cache {
private Map<String, WeakReference<MyObject>new HashMap<>();
public void addToCache(String key, MyObject obj) {
cache.put(key, new WeakReference<>(obj));
}
public MyObject getFromCache(String key) {
WeakReference<MyObject> ref = cache.get(key);
return (ref != null) ? ref.get() : null;
}
}
Finalizers ve Cleaners Kullanımı
finalize() metodunu kullanarak nesne temizleme işlemleri gerçekleştirilebilir, ancak bu yöntem performans sorunlarına yol açabilir. Bunun yerine java.lang.ref.Cleaner sınıfı kullanarak kaynak yönetimi daha verimli bir şekilde gerçekleştirilebilir.
Get BcemreD’s stories in your inbox
Join Medium for free to get updates from this writer.
import java.lang.ref.Cleaner;
public class Resource {
private static final Cleaner cleaner = Cleaner.create();
private final Cleaner.Cleanable cleanable;
public Resource() {
this.cleanable = cleaner.register(this, new State());
}
private static class State implements Runnable {
@Override
public void run() {
// Cleanup resources
}
}
}
Bellek Sızıntıları İçin
Statik Referansları Temizlemek: Statik değişkenler, programın ömrü boyunca bellekte kalır. Kullanılmayan statik referansları temizlemek bellek sızıntılarını önler.
Koleksiyonları Düzenli Temizlemek: Koleksiyonlar (örneğin, ArrayList, HashMap) gereksiz nesneleri tutabilir. Bu koleksiyonları düzenli olarak temizlemek belleği serbest bırakır.
Kapatılabilir Kaynakları Kapatmak: Dosya, veritabanı bağlantıları gibi kapatılabilir kaynakları try-with-resources bloğu kullanarak doğru şekilde kapatmak, kaynak sızıntılarını önler.
Thread Yönetimi: Oluşturulan thread’lerin doğru şekilde sonlandırıldığından emin olmak, bellek sızıntılarını önler. ExecutorService kullanırken shutdown() metodunu çağırarak iş parçacıkları sonlandırılabilir.
Performance Tuning
Java uygulamalarında performans ayarlamaları (performance tuning) yapmak için de çeşitli teknikler ve stratejiler bulunmaktadır. Bu teknikler, uygulamanın daha hızlı ve verimli çalışmasını sağlar. Aşağıda performans ayarlamaları için yapılabilecek bazı önemli unsurları bulabilirsiniz:
1. Profiling ve Monitoring:
- Profilleme (Profiling) Araçları Kullanımı: Uygulamanın darboğazlarını tespit etmek için Java Profiling araçlarını (örneğin, VisualVM, YourKit) kullanılabilir. Bu araçlar, CPU ve bellek kullanımı hakkında ayrıntılı bilgi sağlar.
- Görüntüleme (Monitoring): Uygulamanın çalışma zamanında nasıl davrandığını izlemek için JMX (Java Management Extensions) ve çeşitli monitoring araçları (örneğin, Prometheus, Grafana) kullanılabilir.
2. Bellek Yönetimi ve Garbage Collection Ayarları:
- GC Ayarlarının Yapılandırılması: JVM’nin garbage collection ayarları optimize edilebilir.
-Xmsve-Xmxparametreleri ile heap boyutlarını ayarlanabilir, farklı GC algoritmalarını (örneğin, G1, CMS) denenebilir. - Bellek Sızıntılarının Önlenmesi: Önceki açıklamalarda belirttiğim gibi bellek sızıntılarını önlemek için referansları doğru şekilde yönetmek ve temizlemek önemlidir.
3. Veri Yapıları ve Algoritmalar:
- Doğru Veri Yapılarının Kullanımı: Uygulamanızda doğru veri yapılarını kullanmak performansı artırılır. Örneğin, sık erişilen veri kümeleri için
ArrayListyerineHashMapkullanmak daha hızlı erişim sağlar. - Algoritma Optimizasyonu: Kullanılan algoritmaların zaman ve mekan karmaşıklığını optimize etmek performansı olumlu etkiler.
4. Thread Yönetimi ve Concurrency:
- Efficient Thread Management: Thread pool kullanarak thread yönetimini daha verimli hale getirin.
ExecutorServicekullanarak thread oluşturma ve yönetimini optimize edebilirsiniz. - Synchronization ve Lock Kullanımı: Gereksiz kilitlenmeleri (lock) önlemek için doğru senkronizasyon tekniklerini kullanın.
ReentrantLockveReadWriteLockgibi daha gelişmiş kilit mekanizmalarını kullanarak performansı artırabilirsiniz.
5. I/O Operasyonları:
- Non-Blocking I/O: I/O işlemlerini optimize etmek için non-blocking I/O (NIO) kullanabilirsiniz. Bu, özellikle yüksek trafikli uygulamalarda performansı artırabilir.
Okuma Önerisi
- https://docs.oracle.com/en/java/javase/11/gctuning/introduction-garbage-collection-tuning.html#GUID-223394DF-2E27-4F5D-A7DF-83151EB577BB
- https://blogs.oracle.com/javamagazine/post/understanding-garbage-collectors
- https://docs.oracle.com/cd/B14099_11/idmanage.1012/b14082/gar_coll.htm#:~:text=The%20term%20%22garbage%22%20refers%20to,directory%20is%20called%20garbage%20collection.








