Konuyla ilgili bu makaleyi okudum , ama gerçekten anlamıyorum. Kavramları açıklarken lütfen bana bazı tavsiyelerde bulunun.
Konuyla ilgili bu makaleyi okudum , ama gerçekten anlamıyorum. Kavramları açıklarken lütfen bana bazı tavsiyelerde bulunun.
Yanıtlar:
Java iki farklı türde / sınıf Referans Nesnesi sağlar : güçlü ve zayıf . Zayıf Referans Nesneleri ayrıca yumuşak ve hayalet olarak ayrılabilir .
Gelin nokta nokta gidelim.
Güçlü Referans Nesnesi
StringBuilder builder = new StringBuilder();
Farklı belirtilmezse, bu varsayılan Referans Nesnesi türü / sınıfıdır: builder
güçlü bir Referans Nesnesi. Bu tür başvuru, başvurulan nesneyi GC için uygun hale getirmez. Yani, bir nesneye güçlü Referans Nesneleri zinciri tarafından atıfta bulunulduğunda , çöp toplanamaz.
Zayıf Referans Nesnesi
WeakReference<StringBuilder> weakBuilder = new WeakReference<StringBuilder>(builder);
Zayıf Referans Nesneleri, varsayılan Referans Nesnesi türü / sınıfı değildir ve kullanılması için yukarıdaki örnekteki gibi açıkça belirtilmesi gerekir. Bu tür bir başvuru, referans nesneyi GC için uygun hale getirir. Yani, StringBuilder
bellekteki nesne için ulaşılabilen tek referansın aslında zayıf referans olması durumunda, GC'nin StringBuilder
nesneyi çöp toplamasına izin verilir . Bellekteki bir nesneye yalnızca Zayıf Referans Nesneleri tarafından erişilebildiğinde, otomatik olarak GC için uygun hale gelir.
Zayıflık Seviyeleri
İki farklı zayıflık düzeyi kaydedilebilir: yumuşak ve fantom .
Bir yumuşak Referans nesnesi temelde bellek a'da kalıntılar daha bit zayıf bir referans nesnesi: hiçbir bellek kullanılabilir ve riski vardır kadar normal olarak, GC döngüsü direnç OutOfMemoryError
(bu durumda, bu çıkarılabilir).
Öte yandan, bir hayalet Referans Nesnesi yalnızca bir nesnenin bellekten etkili bir şekilde kaldırıldığını tam olarak bilmek için yararlıdır: normalde , nesnenin kendisini döndürmediği için garip finalize () canlanma / diriliş davranışını düzeltmek için kullanılırlar, ancak sadece bellek varlığını takip etmeye yardım eder .
Zayıf Referans Nesneleri önbellek modüllerini uygulamak için idealdir. Aslında, nesnelere / değerlere güçlü referans zinciri tarafından erişilemediğinde GC'nin bellek alanlarını temizlemesine izin verilerek bir tür otomatik tahliye uygulanabilir. WeakHashMap'in zayıf anahtarları tutması buna bir örnektir .
Zayıf Referans:
Basit bir ifadeyle, zayıf bir referans, bir nesneyi bellekte kalmaya zorlayacak kadar güçlü olmayan bir referanstır. Zayıf referanslar, çöp toplayıcının sizin için erişilebilirliği belirleme yeteneğinden yararlanmanıza izin verir, böylece bunu kendiniz yapmanız gerekmez.
Yumuşak Referans:
Yumuşak bir referans, zayıf bir referans gibidir, ancak referans aldığı nesneyi atmak daha az istekli olur. Sadece zayıf ulaşılabilir bir nesne (en güçlü referansları WeakReferences'dır) bir sonraki çöp toplama döngüsünde atılır, ancak yumuşak bir şekilde erişilebilen bir nesne genellikle bir süre yapışır.
Fantom Referansı:
Fantom referansı, SoftReference veya WeakReference'dan oldukça farklıdır. Nesnesindeki kavraması o kadar yorucudur ki nesneyi bile alamazsınız - get () yöntemi her zaman null değerini döndürür. Böyle bir referans için tek kullanım, ne zaman işaret ettiği nesnenin öldüğünü bildiğiniz gibi, bir ReferenceQueue'ya ne zaman alınacağını takip etmektir.
Bu metin şu adresten alınmıştır: https://weblogs.java.net/blog/2006/05/04/understanding-weak-references
Tek farkı, SoftReference
ve WeakReference
tarafından sağlanan Android Geliştirici .
A SoftReference
ve a arasındaki fark WeakReference
, referansı temizleme ve sıraya koyma kararının verildiği zaman noktasıdır:
A SoftReference
mümkün olduğunca geç temizlenmeli ve sıkılmalıdır, yani VM'nin belleği tükenme tehlikesi varsa.
A WeakReference
, zayıf atıfta bulunduğu bilinir bilinmez temizlenebilir ve sıralanabilir.
Kullandığınız üç terim çoğunlukla Object'in Çöpleri toplamaya uygunluğu ile ilgilidir.
Zayıf Referans :: Nesneyi bellekte kalmaya zorlayacak kadar güçlü olmayan bir referans. Bu, çöp toplayıcının çöp toplama için bu nesneyi toplamaya istekli olması. O GC'yi toplamaya zorlayamazsınız .
Yumuşak Referans :: Aşağı yukarı zayıf referansa benzer. Ancak, nesneyi çöp toplamadaki zayıf referanstan biraz daha güçlü tuttuğunu söyleyebilirsiniz.
Çöp toplayıcılar ilk yaşam döngüsünün kendisinde zayıf referans toplarlarsa, bir sonraki Çöp toplama döngüsünde yumuşak referans toplarlar.
Güçlü Referans :: Yukarıdaki iki tür referansın tam tersidir. Çöpleri toplamak istemezler (Çoğunlukla asla toplanmazlar.)
Daha fazla bilgi için aşağıdaki bağlantıya bakabilirsiniz:
http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/Reference.html
Bu makale güçlü, yumuşak, zayıf ve fantom referanslarını anlamak için süper yardımcı olabilir.
Size bir özet vermek için,
Bir nesneye güçlü bir referansınız varsa, nesne GC (Çöp Toplayıcı) tarafından asla toplanamaz / geri alınamaz.
Bir nesneye (güçlü referanslar olmadan) yalnızca zayıf referanslarınız varsa, nesne bir sonraki GC döngüsünde GC tarafından geri kazanılır.
Bir nesneye yalnızca yumuşak referanslarınız varsa (güçlü referanslar olmadan), nesne yalnızca JVM belleği dolduğunda GC tarafından geri kazanılır.
Nesnenin içine ne zaman gireceğini izlemek için bir nesneye hayali referanslar oluştururuz ReferenceQueue
. Bir kez sen ince taneli sonlandırma yapabileceğini biliyoruz. (Bu size yanlışlıkla referansı vermediğinden nesneyi yanlışlıkla yeniden diriltmenizi önler). Bu konu hakkında ayrıntılı bilgi almak için bu makaleyi okumanızı tavsiye ederim .
Yani güçlü referansların nihai güce sahip olduğunu söyleyebilirsin (GC tarafından asla toplanamaz)
Yumuşak referanslar zayıf referanslardan daha güçlüdür (JVM hafızası bitene kadar GC döngüsünden çıkabilirler)
Zayıf referanslar, yumuşak referanslardan bile daha az güçlüdür (çünkü herhangi bir GC çevriminden kaçamazlar ve nesnenin başka güçlü referansı yoksa geri kazanılırlar).
Restoran Analojisi
Şimdi güçlü bir müşteri iseniz (güçlü referansa benzer), o zaman yeni bir müşteri restorana gelse veya ne olursa olsun, masanızı asla bırakmayacaksınız (yığıntaki bellek alanı). Garson, restorandan ayrılmanız için size söyleme hakkına (hatta sizden talepte bulunmaya) hakkı yoktur.
Yumuşak bir müşteri iseniz (yumuşak referansa benzer), o zaman yeni bir müşteri restorana gelirse, yeni müşteriyi karşılamak için başka boş bir masa kalmadıkça garson sizden tabloyu terk etmenizi istemez. (Diğer bir deyişle, garson sadece yeni bir müşteri devreye girerse ve bu yeni müşteri için başka bir masa kalmamışsa masadan çıkmanızı isteyecektir)
Eğer zayıf bir müşteriyseniz (zayıf referansa benzer), o zaman garson, kendi isteğiyle, (herhangi bir zamanda) restorandan ayrılmanızı isteyebilir: P
4 referans derecesi - Strong, Weak, Soft, Phantom
Güçlü - başvurulan nesneyi GC için uygun hale getirmeyen bir referans türüdür. oluşturucu sınıfları. ör. - StringBuilder
Zayıf - GC için uygun bir referanstır.
Yumuşak - nesnesi, bellek kullanılabilene kadar GC için uygun olan bir referans türüdür. Görüntü önbelleği için en iyisi. Hafıza kullanılabilir olana kadar onları tutacaktır.
Fantom - nesnesi doğrudan GC için uygun olan bir referans türüdür. Yalnızca bir nesnenin bellekten ne zaman kaldırıldığını bilmek için kullanılır.
kullanımları:
Bir nesnenin bellekten ne zaman tam olarak kaldırıldığını belirlemenizi sağlar.
zaman
finalize()
yöntem aşırı GC uygun iki sınıfın nesneleri için, çöp toplama zamanında olay değildir. Bu yüzden fantom referans onları daha önce GC için uygun hale getirirfinalize()
, bu yüzden yığın çoğu çöp olsa bile OutOfMemoryErrors alabilirsiniz .
Zayıf referanslar önbellek modüllerini uygulamak için idealdir.
Bunlar günlük olarak kodladığımız normal nesne referanslarınızdır:
Employee emp = new Employee();
"Emp" değişkeni bir Çalışan nesnesine güçlü bir başvuruda bulunur ve herhangi bir güçlü başvuru zincirinden erişilebilen nesneler çöp toplama için uygun değildir. Genellikle, istediğiniz budur, ancak her zaman değil. Şimdi, bir koleksiyonda veya haritada veritabanından çok sayıda çalışanı aldığımızı ve düzenli olarak üzerinde çok fazla işlem yapmamız gerektiğini varsayalım, bu yüzden performansı korumak için onları önbellekte tutacağız.
Bu kadar iyi ama şimdi farklı verilere ihtiyacımız var ve bu Çalışan nesnelerine ihtiyacımız yok ve bunlara önbellek dışında herhangi bir yerden başvurulmuyor. Hangi bellek sızıntısına neden oluyor, çünkü bu nesneler kullanılmıyor ancak çöp toplama için hala uygun değil ve bunlara referansımız olmadığı için bu nesneleri önbellekten kaldıramıyoruz? Bu yüzden burada ya önbelleğin tamamını el ile boşaltmamız gerekiyor ki bu da sıkıcıdır ya da Zayıf Referanslar gibi başka tür referanslar da kullanabiliriz.
Zayıf bir referans bir nesneyi belleğe sabitlemez ve diğer referanslardan referans alınmadığı takdirde bir sonraki GC döngüsünde GC'd olur. Java tarafından sağlanan WeakReference sınıfını, başka bir yerden referans verilmeyen nesneleri depolamayacak şekilde yukarıdaki tür önbellekler oluşturmak için kullanabiliriz.
WeakReference<Cache> cache = new WeakReference<Cache>(data);
Verilere erişmek için cache.get () öğesini aramanız gerekir. Zayıf referans çöp toplanmışsa bu alma çağrısı null değerini döndürebilir: NPE'leri önlemek için döndürülen değeri kontrol etmeniz gerekir. Java zayıf referanslar kullanan koleksiyonlar sağlar, örneğin WeakHashMap sınıfı anahtarları zayıf değerler olarak saklar (değerleri değil). Anahtar GC'd ise, değer otomatik olarak haritadan da kaldırılır.
Zayıf referanslar da nesneler olduğu için bunları temizlemenin bir yoluna ihtiyacımız var (referansta bulundukları nesne GC'd olduğunda artık kullanışlı değiller). Zayıf bir başvuru için kurucuya bir ReferenceQueue iletirseniz, çöp toplayıcı bu zayıf başvuruyu sonlandırılmadan veya GC'lenmeden önce ReferenceQueue'ya ekler. Bu kuyruğu periyodik olarak işleyebilir ve ölü referanslarla başa çıkabilirsiniz.
SoftReference bir WeakReference gibidir ancak çöplerin toplanması daha az olasıdır. Yumuşak referanslar, bellek talebine yanıt olarak çöp toplayıcının takdirine bağlı olarak temizlenir. Sanal makine, yumuşak bir şekilde erişilebilen nesnelere yapılan tüm yumuşak referansların bir OutOfMemoryError atmadan önce silineceğini garanti eder.
Hayalet referanslar, tüm referans türlerinin en zayıfıdır, bunlara get çağrısı her zaman null değerini döndürür. Bir nesneye, sonlandırıldıktan sonra, ancak ayrılan belleği geri alınmadan önce hayali bir şekilde atıfta bulunulur.
Peki nasıl faydalılar? Bir hayali referans oluşturduğunuzda, daima bir ReferenceQueue iletmeniz gerekir. Bu, nesnenizin ne zaman GC'lendiğini görmek için bir hayalet referans kullanabileceğinizi gösterir.
Hey, sonuçta kesinleşmiş olarak kabul edildiğinde ancak henüz GC'd değilken zayıf referanslar sayılırsa, sonlandırıcı bloktaki nesneye yeni ve güçlü bir referans oluşturabilir ve nesnenin GC'd olmasını engelleyebiliriz. Evet, yapabilirsin ama muhtemelen bunu yapmamalısın. Bu vakayı kontrol etmek için, GC nesnesine yalnızca bir fantom referansı ile ulaşılamadığı sürece her nesne için en az iki kez gerçekleşir. Bu yüzden hafızanızda bol miktarda çöp olsa bile yığınınız tükenebilir. Hayalet referanslar bunu engelleyebilir.
Java'da Referans Türleri (Güçlü, Yumuşak, Zayıf, Fantom) makalem hakkında daha fazla bilgi edinebilirsiniz .