"Merhaba! Size çöp toplama hakkında küçük bir ders daha vermeye karar verdim."

Bildiğiniz gibi, Java makinesi bir nesnenin ne zaman gereksiz hale geldiğini izler ve onu siler.

"Evet. Sen ve Rishi bana daha önce bahsetmiştiniz. Ayrıntıları hatırlamıyorum."

"Tamam. O zaman tekrar üzerinden geçelim."

Çöp toplama - 1

"Bir nesne yaratılır yaratılmaz, JVM onun için bellek ayırır. Nesneye olan ilgi, referans değişkenler kullanılarak izlenir.  Bir nesne, çöp toplama sırasında silinebilir, yani nesneye referans veren hiçbir değişken yoksa belleğin serbest bırakıldığı prosedür. nesne. "

"Bana biraz çöp toplayıcıdan, ne olduğundan ve nasıl çalıştığından bahset."

"Tamam. Eskiden ana iş parçacığında çöp toplama işlemi yapılırdı. Her 5 dakikada bir veya daha sık. Yeterli boş bellek yoksa, Java makinesi tüm iş parçacıklarını askıya alır ve kullanılmayan nesneleri siler."

"Ancak bu yaklaşım artık terk edildi. Yeni nesil çöp toplayıcı, perde arkasında ve ayrı bir iş parçacığında çalışır. Buna eşzamanlı çöp toplama denir."

"Anlıyorum. Bir nesnenin silinip silinmemesine tam olarak nasıl karar veriliyor?"

"Sadece bir nesneye yapılan başvuruların sayısını saymak çok etkili değildir; birbirine başvuruda bulunan ancak başka hiçbir nesne tarafından başvurulmayan nesneler olabilir."

"Yani Java farklı bir yaklaşım benimsiyor.  Java, nesneleri erişilebilir ve ulaşılamaz olarak ayırır.  Bir nesneye, başka bir erişilebilir (canlı) nesne tarafından başvuruluyorsa erişilebilir (canlıdır). Ulaşılabilirlik, iş parçacıklarından belirlenir. Çalışan iş parçacıkları her zaman erişilebilir (canlı) , kimse onlara atıfta bulunmasa bile."

"Tamam. Sanırım anladım."

"Gerçek çöp toplama işlemi nasıl gerçekleşir - gereksiz nesnelerin silinmesi?"

"Çok basit. Java'da bellek geleneksel olarak iki kısma ayrılır ve çöp toplama zamanı geldiğinde, tüm canlı (ulaşılabilir) nesneler belleğin başka bir bölümüne kopyalanır ve eski belleğin tamamı serbest bırakılır."

"Bu ilginç bir yaklaşım. Referansları saymaya gerek yok: erişilebilir tüm nesneleri kopyalayın ve geri kalan her şey çöp."

"Bundan biraz daha karmaşık. Java programcıları, nesnelerin genellikle iki kategoriye ayrıldığını keşfettiler: uzun ömürlü (programın çalıştığı süre boyunca var olan) ve kısa ömürlü (yöntemlerde ve "yerel performans" gerçekleştirmek için gerekli olan) " operasyonlar)."

"Uzun ömürlü nesneleri kısa ömürlü olanlardan ayrı tutmak çok daha verimli. Bunu yapmak için, nesnenin ömrünü belirlemenin bir yolunu bulmak gerekiyordu."

"Böylece, tüm hafızayı «nesillere» ayırdılar. Birinci nesil nesneler, ikinci nesil nesneler vb. Vardır. Hafıza her temizlendiğinde, nesil sayacı 1 artar. uzun ömürlü olarak kaydedilmektedir."

"Bugün, çöp toplayıcı, Java'nın çok karmaşık ve verimli bir parçasıdır. Parçalarının çoğu, tahminlerde bulunan algoritmalara dayalı olarak buluşsal olarak çalışır. Sonuç olarak, genellikle kullanıcıyı "dinlemez".

"Anlam?"

"Java, System.gc () yöntemi kullanılarak çağrılabilen bir çöp toplayıcı ( GC ) nesnesine sahiptir ."

"Silinecek nesnelerin sonlandırma yöntemlerine çağrıları zorlamak için System.runFinalization()'u da kullanabilirsiniz. Ancak gerçek şu ki, Java belgelerine göre bu, ne çöp toplamanın başlayacağını ne de sonlandırmayı ( ) yöntemi çağrılacaktır.  Ne zaman ve ne için çağrılacağına çöp toplayıcı karar verir. "

"Vay! Bunu öğrendiğim iyi oldu."

"Ama dahası da var. Bildiğiniz gibi, Java'da bazı nesneler diğerlerine başvurur. Bu başvuru ağı, bir nesnenin silinip silinmeyeceğini belirlemek için kullanılır."

"Ve bak. Java'nın bu süreci etkilemene izin veren özel referansları var. Onlar için özel sarmalayıcı sınıfları var. İşte onlar:"

" SoftReference  esnek bir referanstır."

" WeakReference  zayıf bir referans."

" PhantomReference hayali bir referanstır."

"Uh... Bu bana iç sınıfları, iç içe sınıfları, iç içe anonim sınıfları ve yerel sınıfları hatırlattı. İsimler farklı, ama ne işe yaradıkları hiç belli değil."

"Söyle bakalım Amigo, programcı olmuşsun. Şimdi sınıf adlarına kızıyorsun, «yeterince bilgilendirici değiller ve bir adla(!) bu sınıfın ne yaptığını, nasıl yaptığını belirlemek imkansız, diyorsun. ve neden"."

"Vay canına. Fark etmedim bile. Ama bu çok açık."

"Tamam. Bu kadar yeter. Size SoftReferences'tan bahsetmeme izin verin."

"Bu referanslar, önbelleğe alma için özel olarak tasarlanmıştır, ancak başka amaçlar için kullanılabilirler - tümü programcının takdirine bağlıdır."

"İşte böyle bir referansın bir örneği:"

Örnek
// Create a Cat object
Cat cat = new Cat();

// Create a soft reference to a Cat object
SoftReference<Cat> catRef = new SoftReference<Cat>(cat);

// Now only the catRef soft reference points at the object
cat = null;

// Now the ordinary cat variable also references the object
cat = catRef.get();

// Clear the soft reference
catRef.clear();

"Bir nesneye yalnızca yumuşak referanslar varsa, o zaman yaşamaya devam eder ve 'yumuşak erişilebilir' olarak adlandırılır."

"Ancak!  Yalnızca esnek referanslarla başvurulan bir nesne, programın yeterli belleği yoksa çöp toplayıcı tarafından silinebilir.  Aniden programın yeterli belleği yoksa, bir OutOfMemoryException atmadan önce , çöp toplayıcı tüm nesneleri siler. yazılımsal referanslarla başvurulacak ve programa bellek ayırmayı yeniden deneyecek."

"Bir istemci programının bir sunucu programından sık sık çeşitli veriler istediğini varsayalım. Sunucu programı, bir kısmını önbelleğe almak için bir SoftReference kullanabilir. Yazılımsal referanslar tarafından ölümden korunan nesneler belleğin büyük bir bölümünü kaplıyorsa, o zaman çöp toplayıcı bunları siler. hepsi çok güzel!"

"Evet. Ben de beğendim."

"Pekala, küçük bir ekleme: SoftReference sınıfının iki yöntemi vardır. get() yöntemi, SoftReference tarafından başvurulan nesneyi döndürür . Nesne, çöp toplayıcı tarafından silindiyse, get () yöntemi aniden boş değer döndürmeye başlar."

"Kullanıcı ayrıca clear() yöntemini çağırarak SoftReference'ı açıkça temizleyebilir . Bu durumda, SoftReference nesnesinin içindeki zayıf bağlantı yok edilecektir."

"Şimdilik bu kadar."

"İlginç hikaye için teşekkürler Ellie. Gerçekten çok ilginçti."