Java'da SoftReference ve WeakReference arasındaki fark nedir?


810

9
SoftReferences genellikle JVM'nin bellekte olmadığını düşündüğünde toplanan WeakReferences türüdür (gerçekten değil ama tartışma uğruna).
Ajeet Ganga

5
@AjeetGanga, GC her çalıştığında gevşek zayıf referanslar her zaman toplanır. Bkz. Stackoverflow.com/a/46291143/632951
Pacerier

Yanıtlar:


927

Gönderen anlama Zayıf Referanslar Ethan Nicholas tarafından,:

Zayıf referanslar

Bir zayıf bir referans , basitçe hafızada kalma bir nesne zorlamak için yeterince güçlü olmayan bir başvurudur. 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. Bunun gibi zayıf bir referans oluşturursunuz:

WeakReference weakWidget = new WeakReference(widget);

ve sonra weakWidget.get()asıl Widgetnesneyi almak için kodun başka bir yerinde kullanabilirsiniz . Tabii ki zayıf referans çöp toplamayı önleyecek kadar güçlü değil, bu yüzden weakWidget.get()aniden geri dönmeye başlayan ( widget'a güçlü referanslar yoksa) bulabilirsiniz. null .

...

Yumuşak referanslar

Bir yumuşak bir referans o gelir nesneyi atmak için daha istekli olduğunu hariç tam olarak zayıf bir referans gibidir. Sadece zayıf ulaşılabilir bir nesne (en güçlü referanslar WeakReferences) bir sonraki çöp toplama döngüsünde atılacaktır, ancak yumuşak bir şekilde erişilebilen bir nesne genellikle bir süre yapışacaktır.

SoftReferencesdeğildir gerekli farklı bir şekilde herhangi bir davranmaya WeakReferencesfakat uygulamada yumuşak ulaşılabilir objeler genelde uzun hafıza bol kaynağı olarak muhafaza edilir. Bu, onları yukarıda açıklanan görüntü önbelleği gibi bir önbellek için mükemmel bir temel yapar, çünkü çöp toplayıcının hem nesnelerin ne kadar ulaşılabilir olduğu konusunda endişelenmesine izin verebilirsiniz (güçlü bir şekilde ulaşılabilir bir nesne önbellekten asla kaldırılmaz) ve ne kadar kötü olursa olsun tükettikleri hafızaya ihtiyaç duyarlar.

Ve Peter Kessler bir yorum ekledi:

Sun JRE, SoftReferences'ı WeakReferences'dan farklı olarak ele alır. Kullanılabilir bellek üzerinde baskı yoksa, SoftReference tarafından başvurulan nesneyi tutmaya çalışırız. Bir ayrıntı: "-client" ve "-server" JRE'leri için politika farklıdır: -client JRE, yığını genişletmek yerine SoftReferences'ı temizlemeyi tercih ederek ayak izinizi küçük tutmaya çalışırken -server JRE ise net SoftReferences yerine yığın (mümkünse) genişletmeyi tercih ederek yüksek performans. Tek beden herkese olmaz.



arşiv artık mevcut değil
user1506104

209

Zayıf referanslar hevesle toplanmaktadır. GC bir nesneye zayıf erişilebildiğini (yalnızca zayıf referanslarla ulaşılabilir) bulursa, o nesneye zayıf referansları derhal temizler. Bu nedenle, programınızın aynı zamanda bir sınıfla ilgili önbelleğe alınmış yansıma bilgileri veya bir nesne için bir sarıcı vb. ilişkili olduğu nesneden sonra tutulması mantıklı değil GC-ed. Zayıf başvuru temizlendiğinde, kodunuzun bir yerde yokladığı bir başvuru kuyruğunda sıralanır ve ilişkili nesneleri de atar. Yani, bir nesne hakkında fazladan bilgi tutarsınız, ancak söz konusu nesne ortadan kalktığında bu bilgilere gerek yoktur. Aslında, belirli durumlarda WeakReference alt sınıfını yapabilir ve nesne hakkında ilişkili ek bilgileri WeakReference alt sınıfının alanlarında saklayabilirsiniz. WeakReference'ın bir diğer tipik kullanımı, kanonik örnekleri korumak için Haritalar ile bağlantılıdır.

Öte yandan SoftReferences, harici, yeniden oluşturulabilir kaynakların önbelleğe alınması için iyidir, çünkü GC genellikle bunları temizlemeyi geciktirir. OutOfMemoryError atılmadan önce tüm SoftReferences'ın temizleneceği garanti edilir, bu nedenle teorik olarak OOME'ye neden olamazlar [*].

Tipik kullanım örneği, dosyadaki içeriklerin ayrıştırılmış bir formunu tutmaktır. Bir dosyayı yüklediğiniz, ayrıştırdığınız ve ayrıştırılmış gösterimin kök nesnesine SoftReference uygulayacağınız bir sistem uygularsınız. Bir dahaki sefere dosyaya ihtiyacınız olduğunda, SoftReference üzerinden almaya çalışacaksınız. Eğer geri getirebilirseniz, kendinize başka bir yük / ayrıştırma bağışladınız ve GC bu arada temizlediyse, yeniden yüklersiniz. Bu şekilde, performans optimizasyonu için boş bellek kullanırsınız, ancak OOME riskini almazsınız.

Şimdi [*] için. SoftReference tutmak kendi içinde bir OOME'ye neden olamaz. Öte yandan, bir görev için yanlışlıkla SoftReference kullanıyorsanız, bir WeakReference'ın kullanılması gerekiyorsa (yani, bir Nesne ile ilişkili bilgileri bir şekilde güçlü bir şekilde referans alırsınız ve Referans nesnesi temizlendiğinde atarsınız), OOME ReferenceQueue'yu yoklayan ve ilişkili nesneleri atayan kodunuz zamanında çalışmayabilir.

Bu nedenle, karar kullanıma bağlıdır - yapılandırılması pahalı olan, ancak yine de diğer verilerden yeniden oluşturulabilen bilgileri önbelleğe alıyorsanız, yumuşak referanslar kullanın - bazı verilerin kanonik örneğine referansta bulunuyorsanız veya bir nesneye "sahip olmadan" referans vermesi (böylece GC'nin olmasını engellemesi) zayıf bir referans kullanın.


14
Özellikle zayıf nesnelerin ne zaman kullanılacağının açıklaması için kullanışlıdır.
Jack BeNimble

A'nın doğru kullanımı ile ilgili önemli bir nokta WeakReference, kişinin onu kullanması gereken yerlerde, referansın kapsam dışına çıktıktan sonra bir süre geçerli kalması tolere edilebilir, ancak istenmez.
supercat

Ben her zaman anahtar / değer nesnesine zayıf başvuru üretirse WeakHashMap kullanımının ne olduğunu anlamak için mücadele?

@supercat, GC çalışmalarını gözlemlemek için sadece bir uygun kullanımı WeakReferencevardır. Ayrıntılara bakın: stackoverflow.com/a/46291143/632951
Pacerier

1
@Pacerier: Bu yazının yazarı yanlış. Etkinlik aboneliği gibi diğer kullanım senaryolarını ihmal eder, ikinci noktası saçmadır ve üçüncü noktası bir programcının mümkün olmayan şeyleri yapabileceğini varsayar. İlk noktası makul, ama söylediklerimle doğrudan bağlantılı. Örneğin, kodun sık sık büyük değişmez nesneler oluşturup karşılaştırması gerekiyorsa, kod zaten var olup olmadıklarına bakılmaksızın yeni nesneler oluşturuyorsa, yapı parçası genellikle daha ucuz olur, ancak bir nesne ile kendisi arasında bir karşılaştırma (özdeş referanslar) ...
supercat

155

Java dilinde ; güçlü, Yumuşak, Zayıf ve Hayalet

Bir güçlü bir referans GC ile koleksiyonundan ifade nesne koruyan normal referanstır. Yani asla çöp toplamaz.

Bir Yumuşak referans çöp toplayıcı tarafından toplama işlemi için uygundur, ama muhtemelen onun bellek gereklidir kadar tahsil edilmeyecektir. yani çöp daha önce toplar OutOfMemoryError.

Bir Zayıf referans GC ile koleksiyonundan bir başvurulan nesneyi korumaz bir referanstır. Çöp, Güçlü veya Yumuşak referans olmadığında toplanır.

Bir Phantom referansı , sonlandırıldıktan sonra, ancak ayrılan belleği geri kazanılmadan önce, bir nesneye hayali olarak atıfta bulunulan bir referanstır.

Kaynak

Analoji: Bir JVM'nin bir krallık olduğunu, Object'in krallığın bir kralı olduğunu ve GC krallığın (nesne) öldürmeye çalışan bir krallığın saldırganı olduğunu varsayalım.

  • Kral Güçlü olduğunda , GC onu öldüremez.
  • Kral Yumuşak olduğunda GC ona saldırır, ancak Kral kaynak bulunana kadar krallığı koruma altına alır.
  • Kral Zayıf olduğunda GC ona saldırır, ancak krallığı koruma olmadan yönetir.
  • Kral Phantom olduğunda , GC zaten onu öldürdü, ancak kral ruhundan ulaşılabilir.

7
Yumuşak referans ... until memory is availablemantıklı değil. Bunu mu demek istediniz is eligible for collection by garbage collector, but probably won't be collected until its memory is needed for another use?
ToolmakerSteve

1
evet, bellek toplanana kadar çöp toplayıcı referansı toplamaz.
Premraj

2
Benden çok fazla bla bla bla +1 olmadan basit açıklanmış şeyleri seviyorum!
Adelin

3
Yenilikçi örnek ile mükemmel özet
Ravindra babu


77

Zayıf Referans http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html

İlke: weak reference çöp toplama ile ilgilidir. Normalde, bir veya daha fazlasına sahip nesne referenceçöp toplama için uygun olmaz.
Yukarıdaki ilke, geçerli olduğunda geçerli değildir.weak reference . Bir nesnenin diğer nesnelerle yalnızca zayıf bir referansı varsa, o zaman çöp toplama için hazırdır.

Aşağıdaki örneğe bakalım: MapAnahtarın bir nesneye başvurduğu Nesneleri olan bir.

import java.util.HashMap;   
public class Test {

    public static void main(String args[]) {
        HashMap<Employee, EmployeeVal> aMap = new 
                       HashMap<Employee, EmployeeVal>();

        Employee emp = new Employee("Vinoth");
        EmployeeVal val = new EmployeeVal("Programmer");

        aMap.put(emp, val);

        emp = null;

        System.gc();
        System.out.println("Size of Map" + aMap.size());

    }
}

Şimdi programın yürütülmesi sırasında yaptık emp = null. MapOlduğu gibi tutma anahtarı burada hiçbir mantıklı null. Yukarıdaki durumda, nesne çöp toplanmaz.

WeakHashMap

WeakHashMap, girişlerin ( key-to-value mappings) artık girişlerden alınamadığında kaldırılacağı yerdir .Map .

Yukarıdaki örneği WeakHashMap ile aynı şekilde göstereyim

import java.util.WeakHashMap;

public class Test {

    public static void main(String args[]) {
        WeakHashMap<Employee, EmployeeVal> aMap = 
                    new WeakHashMap<Employee, EmployeeVal>();

        Employee emp = new Employee("Vinoth");
        EmployeeVal val = new EmployeeVal("Programmer");

        aMap.put(emp, val);

        emp = null;

        System.gc();
        int count = 0;
        while (0 != aMap.size()) {
            ++count;
            System.gc();
        }
        System.out.println("Took " + count
                + " calls to System.gc() to result in weakHashMap size of : "
                + aMap.size());
    }
}

Çıktı: Şununla 20 calls to System.gc()sonuçlandı aMap size: 0.

WeakHashMapdiğer Mapsınıflar gibi güçlü referanslar değil, anahtarlar için sadece zayıf referanslar vardır . Kullanmış olsanız da, değere veya anahtara güçlü bir şekilde başvurulduğunda dikkat etmeniz gereken durumlar vardır WeakHashMap. Bu, nesneyi bir WeakReference öğesine sararak önlenebilir .

import java.lang.ref.WeakReference;
import java.util.HashMap;

public class Test {

    public static void main(String args[]) {
        HashMap<Employee, EmployeeVal> map = 
                      new HashMap<Employee, EmployeeVal>();
        WeakReference<HashMap<Employee, EmployeeVal>> aMap = 
                       new WeakReference<HashMap<Employee, EmployeeVal>>(
                map);

        map = null;

        while (null != aMap.get()) {
            aMap.get().put(new Employee("Vinoth"),
                    new EmployeeVal("Programmer"));
            System.out.println("Size of aMap " + aMap.get().size());
            System.gc();
        }
        System.out.println("Its garbage collected");
    }
}

Yazılım Referansları.

Soft Referencezayıf referanstan biraz daha güçlüdür. Yumuşak referans çöp toplanmasına izin verir, ancak çöp toplayıcıya yalnızca başka bir seçenek yoksa temizlemesini ister.

Çöp toplayıcı, yumuşak erişilebilen nesneleri zayıf erişilebilen nesnelerle olduğu gibi agresif bir şekilde toplamaz - bunun yerine yalnızca belleğe gerçekten ihtiyaç duyması durumunda yumuşak erişilebilen nesneleri toplar. Yumuşak referanslar çöp toplayıcısına, "Bellek çok sıkı olmadığı sürece, bu nesneyi saklamak istiyorum. Ama eğer bellek gerçekten sıkılaşırsa, devam edin ve toplayın ve ilgileneceğim Bununla." Çöp toplayıcının atmadan önce tüm yumuşak referansları temizlemesi gerekir OutOfMemoryError.


5
Bir alabilirsiniz NullPointerExceptionin aMap.get().put(...).
xehpuk

İlk HashMap örneğiniz yanlış görünüyor. "AMap.put (emp, val);" hem 'emp' hem de 'val' güçlü referanslardır. Dahili olarak, 'emp = null; " sadece "emp" değişkenini geçersiz kılarsınız, ancak hash haritasına dahili olarak değil (orijinal Employee nesnesini tutar). Bu nedenle, karma harita, dışarıdaki 'emp' değişkeniyle ne yaparsanız yapın, hala 'emp' için güçlü bir referansa sahip olacaktır.
Tiago

@Tiago. Hayır. Muhtemelen "ilk örnek" ile örneğe atıfta bulunuyorsunuz WeakHashMap(çünkü Zayıf davranışı gösteren ilk örnek budur). "WeakHashMap" için doc bak: "An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. " WeakHashMap kullanarak tüm noktasının olmasıdır sen pass-bir WeakReference / beyan etmek gerekmez; WeakHashMap bunu sizin için dahili olarak yapar. docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html
ToolmakerSteve

ZayıfHashMap boyutu ile sonuçlanmak üzere System.gc () için 0 çağrı aldı: 0 ikinci programınızın çıktısı mı?
Adelin

1
Başka bir örneği için WeakHashMapgirişleri sadece kaldırılır nasıl örnek uygulama gösterimiyle eylem, sonra çöp toplama çalıştırır, bkz benim cevap Soru, Is WeakHashMap büyüyen ya da çöp anahtarlarını temizleyin geliyor? .
Basil Bourque

50

Yumuşak referans ile zayıf referans arasındaki tek gerçek fark,

çöp toplayıcı, yumuşak bir şekilde erişilebilen bir nesneyi geri alıp almayacağınıza karar vermek için algoritmalar kullanır, ancak her zaman zayıf bir şekilde erişilebilir bir nesneyi geri alır.


@ Ataorras, Samir. Bu cevabı burada genişlettim: stackoverflow.com/a/46291143/632951
Pacerier

25

SoftReferenceönbellekler için tasarlanmıştır. WeakReferenceAksi takdirde ulaşılamayan bir nesneye başvurduğu tespit edildiğinde , derhal temizlenecektir. SoftReferenceolduğu gibi bırakılabilir. Genellikle boş bellek miktarı ve silinmesi gerekip gerekmediğini belirlemek için en son kullanılan zamanla ilgili bazı algoritmalar vardır. Geçerli Sun algoritması, Java yığınında megabayt bellek kadar boşta kaldığı sürece referansı temizlemektir (yapılandırılabilir, sunucu HotSpot, ayarlandığı gibi mümkün olan en fazla yığını denetler -Xmx). Aksi takdirde erişilemezse, atılmadan SoftReferenceönce silinecektir OutOfMemoryError.


9
Ancak Android'de önbellekler için tavsiye edilmez developer.android.com/reference/java/lang/ref/…
Yaroslav Mytkalyk

4
@DoctororDrive tbf soru dalvik değil, java hakkındaydı! :-P
fabspro

2
@YaroslavMytkalyk, Açıkçası, Android bir sınıfın davranışını yeniden yazmak istiyorsa, kendi ad alanını kullanmalıdır java.lang. Eşanlamlıların bu şekilde kötüye kullanılması hiç kimseye iyi bir şey yapmaz.
Pacerier

9

Bu makale güçlü, yumuşak, zayıf ve hayali referansları anlamak için çok yardımcı olabilir.


Size bir özet vermek için,

Yalnızca zayıf referanslarınız varsa nesneye (güçlü referanslar olmadan) 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.


Yani güçlü referansların nihai güce sahip olduğunu söyleyebilirsiniz. (GC tarafından asla toplanamaz)

Yumuşak referanslar güçlüdür zayıf referanslardan daha (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 döngüsünü çıkaramazlar ve nesnenin başka güçlü referansı yoksa geri kazanılırlar).


Restoran Analojisi

  • Garson - GC
  • Sen - yığın halinde 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ılmak için size söyleme hakkına (hatta sizden talepte bulunmaya) hakkı yoktur.

Eğer bir ise yumuşak müşteri (yumuşak referans benzer) Yeni bir müşteri restoranda gelirse yeni müşteri karşılamak için sol başka hiçbir boş masa olmadığı sürece, o zaman, garson masayı terk etmek 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 bir ise zayıf müşteri (zayıf referans benzer), sonra garson, onun iradesiyle, (zamanın herhangi bir noktasında) restoran terk etmenizi isteyebilir: P


7

Tek Gerçek Fark

Başına doc , gevşek WeakReferences gerekir çalışan bir GC ile temizlenir.

Başına doc , gevşek SoftReferences gerekir OOM önce temizlenecek atılır.

Tek gerçek fark bu. Diğer her şey sözleşmenin bir parçası değildir. (En son dokümanların sözleşmeye bağlı olduğunu varsayacağım.)

SoftReferences yararlıdır. Belleğe duyarlı önbellekler WeakReferences değil SoftReferences kullanır.


WeakReference'ın tek uygun kullanımı GC çalışmasını gözlemlemektir. Bunu, nesnesi hemen kapsam dışına çıkan yeni bir WeakReference oluşturarak yaparsınız, ardından null değerinden çıkmaya çalışın weak_ref.get(). Olduğu zamannull , bu süre arasında GC'nin koştuğunu öğrenirsiniz.

WeakReference yanlış kullanımına gelince , liste sonsuzdur:

  • öncelik-2 yazılımını uygulamak için berbat bir saldırı, böylece bir tane yazmak zorunda kalmazsınız, ancak yedek bellek olsa bile önbellek her GC çalışmasında temizleneceği için beklendiği gibi çalışmaz . Filler için https://stackoverflow.com/a/3243242/632951 adresine bakın . (Ayrıca, 2'den fazla önbellek önceliğine ihtiyacınız varsa? Hala bunun için gerçek bir kütüphaneye ihtiyacınız olacak.)

  • Berbat bir hack varolan sınıfının bir nesne ile ilişkilendirmek verilere, henüz senin GC sizin weakreferences oluşturulduktan sonra bir mola karar verdiğinde bir bellek sızıntısı (OutOfMemoryError) oluşturur. Ayrıca, çirkin ötesinde: Daha iyi bir yaklaşım tuples kullanmaktır.

  • sınıfın kendisini alt sınıflandırılamayan bir sinire sahip olduğu ve çağırmanız gereken mevcut bir işlev kodunda kullanıldığı, mevcut bir sınıfın nesnesiyle verileri ilişkilendirmek için berbat bir saldırı . Böyle bir durumda, uygun çözüm ya sınıfı düzenlemek ve alt sınıflanabilir yapmak ya da işlevi düzenlemek ve sınıf yerine arabirim almasını sağlamak ya da alternatif bir işlev kullanmaktır.


Anahtar türlerinin equals()sadece nesne kimliği olduğu bir önbellek ne olacak ? Yumuşak referanslar orada bir israf gibi görünüyor, çünkü bir anahtar nesneye artık güçlü bir şekilde ulaşılamadığında, hiç kimse bu eşlemeyi tekrar aramayacak.
HighCommander4

Katılmıyorum. GC'yi yine de etkilemek istemediğinizde WeakReference'ı kullanın (Bir nesne başvurusunu kaydetmek ve daha sonra herhangi bir tercih olmaksızın hala var olup olmadığını daha sonra kontrol etmek isteyebilirsiniz). Nesneyi korumak ve denemek için GC'yi etkilemek istiyorsanız SoftReference kullanın (yani, GC'nin bunu tutmasını tercih ettiğinizde).
David Refaeli

WeakReference'ın nerede kullanıldığına iyi bir örnek, bağlamın bir örneğini tutmak için Android'in AsyncTask'ındadır. Bu şekilde içerik ölürse (etkinlik - ekran döndürme vb.), AsyncTask'ın buna güçlü bir referansı olmaz ve bu nedenle çöp toplanabilir. Kontrol youtu.be/...
David Refaeli

3

Java'da altı tür nesne erişilebilirliği durumu:

  1. Güçlü ly ulaşılabilir nesneler - GC olmaz toplamak ( bellek tarafından işgal geri nesnesinin bu tür). Bunlara bir kök düğümü veya başka bir güçlü ulaşılabilir nesne (yani yerel değişkenler, sınıf değişkenleri, örnek değişkenler vb. Yoluyla) erişilebilir .
  2. Yumuşak ve ulaşılabilir nesneler - GC , bellek çekişmesine bağlı olarak bu tür nesneleri toplamaya çalışabilir . Bunlara bir veya daha fazla yumuşak referans nesnesi aracılığıyla kökten erişilebilir
  3. Zayıf ly ulaşılabilir nesneler - GC gerekir nesnenin bu tür toplamak. Bunlara bir veya daha fazla zayıf referans nesnesi aracılığıyla kökten erişilebilir
  4. Yeniden dirilebilen nesneler - GC zaten bu nesneleri toplama sürecindedir. Ancak eyaletlerden birine geri dönebilirler - Güçlü / Yumuşak / Zayıf Bazı finalizerlerin uygulanmasıyla
  5. Phantom ly ulaşılabilir nesne - GC zaten bu nesneleri toplama sürecindedir ve herhangi bir sonlandırıcı tarafından yeniden diriltilemediğine karar vermiştir (bir finalize () yönteminin kendisini bildirirse, sonlandırıcı çalıştırılacaktır) . Bunlara bir veya daha fazla fantom referans nesnesi aracılığıyla kökten erişilebilir
  6. Ulaşılamaz nesne - Bir nesneye ne güçlü, yumuşak, zayıf ne de hayalet ulaşılabilir değildir ve yeniden canlandırılamaz. Bu nesneler ıslah için hazır

Daha fazla ayrıntı için: https://www.artima.com/insidejvm/ed2/gc16.html «daralt


4
Fantom referanslarının iyi bir açıklaması değil. Ayrıca, 4 türü garip bir sırayla listelediniz. "fantom" en zayıf tiptir, en güçlü tip değildir. Bunları listelemek için geleneksel düzen "güçlü, yumuşak, zayıf, fantom" dur. Ve hayalet nesnelerin önbellekleme mekanizmaları için kullanıldığı fikrini nereden bulduğunuzu bilmiyorum. AFAIK, sıradan bir programcının çalışacağı bir şey değil, sadece GC tarafından görülen geçici bir durumdur.
ToolmakerSteve

@ToolmakerSteve ve hepsi - Birkaç şey için özür 1. cevabımın önceki sürümünde Phantom referanslarının yanlış açıklaması ve 2. Hataları düzeltmede gecikme. Şimdi cevap, hatalar düzeltilerek iyileştirildi
V.Vidyasagar

1

Zayıf bir şekilde atıfta bulunulan bir nesnenin yalnızca SADECE zayıf referansları olduğunda toplanacağının farkında olunmalıdır. Tek bir güçlü referansı varsa, ne kadar zayıf referansı olursa olsun toplanmaz.


Bu sağduyu ... aynı yumuşak soluk ve hayalet için de geçerlidir.
Pacerier

1

Bir eylem içi bellek kullanımı özelliği vermek için, ağır nesneler altında Ağır nesneler ile Güçlü, Yumuşak, Zayıf ve Fantom referansları ile programın sonuna kadar saklayarak bir deneme yaptım. Daha sonra yığın kullanımı ve GC davranışı izlendi . Bu metrikler duruma göre değişebilir, ancak kesinlikle üst düzey bir anlayış sağlar. Aşağıda bulgular verilmiştir.

Ağır yük altında Yığın ve GC Davranışı

  • Güçlü / Sert Referans - Program devam ettikçe, JVM tutulan güçlü referanslı nesneyi toplayamadı. Sonunda "java.lang.OutOfMemoryError: Java yığın alanı" nda sona erdi
  • Soft Reference - Program devam ettikçe yığın kullanımı artmaya devam etti, ancak ESK gen GC, maksimum yığına yaklaştıkça oldu. GC, program başladıktan sonra biraz sonra başladı.
  • Zayıf Referans - Program başlar başlamaz, nesneler neredeyse anında toplanmaya ve toplanmaya başladı. Çoğunlukla nesneler genç nesil çöp toplamada toplandı.
  • Fantom Referansı - Zayıf referansa benzer şekilde, fantom referanslı nesneler de sonlandırılmaya başlandı ve hemen çöp toplandı. Eski nesil GC yoktu ve tüm nesneler genç nesil çöp toplamada toplanıyordu.

Bu deney için daha ayrıntılı grafikler, istatistikler ve gözlemler alabilirsiniz .


0

WeakReference : yalnızca zayıf başvurulan nesneler her GC döngüsünde (küçük veya dolu) toplanır.

SoftReference : yalnızca yumuşak başvurulan nesneler toplandığında şunlara bağlıdır:

  1. -XX: SoftRefLRUPolicyMSPerMB = N bayrağı (varsayılan değer 1000, yani 1 saniye)

  2. Yığındaki boş bellek miktarı.

    Misal:

    • yığın 10MB boş alana sahiptir (tam GC'den sonra);
    • XX: SoftRefLRUPolicyMSPerMB = 1000

    Daha sonra yalnızca SoftReference tarafından başvurulan nesne, en son erişildiği süre 10 saniyeden fazlaysa toplanır.

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.