Java: güçlü / yumuşak / zayıf / fantom referansı arasındaki fark


179

Konuyla ilgili bu makaleyi okudum , ama gerçekten anlamıyorum. Kavramları açıklarken lütfen bana bazı tavsiyelerde bulunun.



4
Bu belgeyi okudum, ne fark ettiğimi hayal etmeme yardımcı olmuyor. (belki de okunması zor bir belge olduğu için)

14
Bu makaleyi okuduysanız ve hâlâ anlamıyorsanız, bu konuyla ilgili özel sorularınız mı var? "Lütfen Foo'yu bana açıklayın", "işte anlamadım", "" Anlamadım "ifadesine, hangi parçaları alamayacağınızla ilgili ayrıntılar olmadan yanıt vermek zor.
yshavit


@LouisWasserman Üst bağlantı artık geçerli değil.
Mehraj Malik

Yanıtlar:


142

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 .

  • kuvvetli
  • Güçsüz
    • yumuşak
    • fantom

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: buildergüç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, StringBuilderbellekteki nesne için ulaşılabilen tek referansın aslında zayıf referans olması durumunda, GC'nin StringBuildernesneyi çö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 .


76

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


1
Bu yanıttaki her şey doğru görünse de, bağlantılı web sayfasında bir hata olabileceği gibi bana da benziyor. Paket java.lang.ref için Javadoc PhantomReference bir nesne (SoftReference aksine) bir PhantomReference o kutu atıfta nesneden önce dequeued gerektiğini ima "ulaşılabilir fantom" artık sonrasına kadar toplanan çöp olmadığını düşündürmektedir için ve bu çöp toplanmalı ... ve enküre edilmesi, ilgili belleğin boşaltıldığını göstermez.
Theodore Murdock

2
Kayıt için, blog yazısının doğru olduğu bir dünyada yaşamayı tercih ederim.
Theodore Murdock

1
@TheodoreMurdock Javadoc doğrudur. Fantom referansı çöp toplamayı engellemez. Bir nesne sıkıldığında, sonlandırıcılar zaten çalıştığından bir sonlandırıcı tarafından bile kaydedilemez. Öldü, ama henüz gitmedi.
Leliel

@Leliel Aslında bir fantom referans yapar o kuyruğa sonra bir hata erken çıkmak için bir temizleme ipliği neden zaman Geçenlerde bu fark ... Aslında zorlaştırıyor çöp toplama. Fantom referanslarının varlığı, başvurulan her fantomun yığın dökümünde tutulduğundan, toplama için kullanılamıyorsa ... kuyruğu işleyemezseniz veya kuyruğu işlerken fan referansını gc için uygun hale getiremezse ( ve (fantom referansını temizlemeyin), bellek sızıntısı hem fantom referansını hem de başvurulan nesneyi içerecektir.
Theodore Murdock

25

Tek farkı, SoftReferenceve WeakReferencetarafından sağlanan Android Geliştirici .

A SoftReferenceve a arasındaki fark WeakReference, referansı temizleme ve sıraya koyma kararının verildiği zaman noktasıdır:

  • A SoftReferencemü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.


16

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


3
Bunun yanlış olduğunu düşünüyorum - "Çöp toplayıcıları ilk yaşam döngüsünün kendisindeki zayıf referansı toplarsa, bir sonraki Çöp toplama döngüsünde yumuşak referansı toplar." Bu şekilde olmak zorunda değil, GC'nin art arda çalıştığından nasıl bu kadar emin olabilirsiniz? GC, başvurulan nesnelerin 2. ve 3. çalışmalarda bile yaşamasına izin verebilir. Bunun için dokümantasyon yok, eğer varsa lütfen bağlantıyı belirtin.
Saurabh Patil

2
Ayrıca, cevabınız biraz belirsiz, şu cümleye bakın 'Zayıf referans gibi aşağı yukarı aynı. Ancak nesneyi çöp toplamadaki zayıf referanstan biraz daha güçlü tuttuğunu söyleyebilirsiniz. ' - açıkça benzerlikler değil, farkı soruyor, tüm bu kelimeler konuya netlikten daha fazla karışıklık katıyor.
Saurabh Patil

@SaurabhPatil - Yorumunuzu kaçırdınız. İşte cevaplar. 1. "açıkça farkları ve benzerlikleri soruyor" - Sorunun açıklamasına bakın ("sadece" başlık değil) "Lütfen bana biraz tavsiye verin ve lütfen tarif etmek için bana bir örnek verin". 2. "Ama nesneyi biraz daha fazla tuttuğunu söyleyebilirsiniz ...." Bence SOF aşağı oylama ve yeni cevaplar vermek için bir seçenek sunuyor.
Sabya

14

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

  • Garson - GC
  • Sen - yığın nesne
  • Restoran alanı / alanı - Yığın alanı
  • Yeni Müşteri - Restoranda masa isteyen yeni nesne

Ş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


10

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ı:

  1. Bir nesnenin bellekten ne zaman tam olarak kaldırıldığını belirlemenizi sağlar.

  2. 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 getirir finalize(), bu yüzden yığın çoğu çöp olsa bile OutOfMemoryErrors alabilirsiniz .

Zayıf referanslar önbellek modüllerini uygulamak için idealdir.


10

Güçlü Referanslar

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 Referanslar

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.

Yazılım Referansları

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.

Phantom Referansları

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 .


diğer referanslardan reddedilmezse, zayıf döngülerin bir sonraki döngüde GC'leneceğini yazdınız ... ama aynı şey güçlü referanslar için de olmamalı mı? eğer güçlü reddeye herhangi bir şekilde erişilmezse, o zaman temizlenir ... o zaman öyleyse fark tekrar nerede ...? #confused
filemonczyk

1
Bir nesneden s1 (güçlü) ve s2 (güçlü) deniliyorsa, nesne hem s1 hem de s2 referansı kaldırılana kadar çöp toplama için uygun olmayacak, ancak nesne s1 (zayıf) ve s2 ( strong) sonra nesne yalnızca s2'den kaydı silindiğinde bir sonraki GC döngüsünde çöp toplama için uygun olacaktır, çünkü s1 zayıf bir referans olduğundan ve nesnenin zayıf dışında başka bir referansı yoksa GC için uygundur
Naresh Joshi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.