Qual è la differenza tra SoftReference e WeakReference in Java?


811

9
Le SoftReferences sono un tipo di (non proprio, ma per amor di discussione), le Debole Riferimenti che di solito vengono raccolte quando JVM pensa che sia esaurito.
Ajeet Ganga,

5
@AjeetGanga, i riferimenti deboli sciolti vengono sempre raccolti ogni volta che il GC funziona. Vedere stackoverflow.com/a/46291143/632951
Pacerier

Risposte:


927

Da capire i riferimenti deboli , di Ethan Nicholas:

Riferimenti deboli

Un riferimento debole , in poche parole, è un riferimento che non è abbastanza forte da forzare un oggetto a rimanere in memoria. I riferimenti deboli ti consentono di sfruttare la capacità del garbage collector di determinare la raggiungibilità per te, quindi non devi farlo da solo. Si crea un riferimento debole come questo:

WeakReference weakWidget = new WeakReference(widget);

e poi altrove nel codice è possibile utilizzare weakWidget.get()per ottenere l' Widgetoggetto reale . Naturalmente il riferimento debole non è abbastanza forte da impedire la garbage collection, quindi potresti trovare (se non ci sono riferimenti forti al widget) che weakWidget.get()improvvisamente inizia a tornare null.

...

Riferimenti morbidi

Un riferimento morbido è esattamente come un riferimento debole, tranne per il fatto che è meno desideroso di gettare via l'oggetto a cui si riferisce. Un oggetto che è solo debolmente raggiungibile (i riferimenti più forti ad esso sono WeakReferences) verrà scartato al successivo ciclo di raccolta dei rifiuti, ma un oggetto che è delicatamente raggiungibile si bloccherà generalmente per un po '.

SoftReferencesnon sono tenuti a comportarsi diversamente da WeakReferences, ma in pratica gli oggetti facilmente raggiungibili vengono generalmente mantenuti fintanto che la memoria è abbondante. Questo li rende un'ottima base per una cache, come la cache di immagini descritta sopra, poiché puoi lasciare che il garbage collector si preoccupi sia di quanto siano raggiungibili gli oggetti (un oggetto fortemente raggiungibile non verrà mai rimosso dalla cache) sia di quanto male ha bisogno della memoria che stanno consumando.

E Peter Kessler ha aggiunto in un commento:

Sun JRE tratta le SoftReferences in modo diverso dalle DeboleReferenze. Tentiamo di aggrapparci all'oggetto a cui fa riferimento un SoftReference se non c'è pressione sulla memoria disponibile. Un dettaglio: i criteri per i JRE "-client" e "-server" sono diversi: il JRE -client cerca di ridurre l'ingombro preferendo cancellare SoftReferences piuttosto che espandere l'heap, mentre il JRE -server cerca di mantenere il tuo prestazioni elevate preferendo espandere l'heap (se possibile) piuttosto che cancellare SoftReferences. Una taglia non va bene per tutti.


7
Post non più disponibile, puoi trovarlo sulla macchina del ritorno: web.archive.org/web/20061130103858/http://weblogs.java.net/blog/…
riccardo.tasso,

questa volta, l'archivio non è più disponibile
user1506104

209

I riferimenti deboli vengono raccolti avidamente. Se GC rileva che un oggetto è debolmente raggiungibile (raggiungibile solo attraverso riferimenti deboli), cancella immediatamente i riferimenti deboli a quell'oggetto. Come tali, sono utili per mantenere un riferimento a un oggetto per il quale il tuo programma conserva anche (informazioni fortemente riferite) "informazioni associate", come informazioni di riflessione memorizzate nella cache su una classe o un wrapper per un oggetto, ecc. Tutto ciò che rende non ha senso mantenere l'oggetto a cui è associato è GC-ed. Quando il riferimento debole viene cancellato, viene accodato in una coda di riferimento che il codice esegue il polling da qualche parte e scarta anche gli oggetti associati. Cioè, si conservano ulteriori informazioni su un oggetto, ma tali informazioni non sono necessarie una volta che l'oggetto a cui si riferisce scompare. In realtà, in alcune situazioni è anche possibile sottoclassare WeakReference e conservare le informazioni aggiuntive associate sull'oggetto nei campi della sottoclasse WeakReference. Un altro uso tipico di WeakReference è in combinazione con Maps per mantenere le istanze canoniche.

Le SoftReferenze sono invece utili per la memorizzazione nella cache di risorse esterne e ricreabili poiché il GC in genere ritarda a cancellarle. È comunque garantito che tutte le SoftReferences verranno cancellate prima che venga lanciato OutOfMemoryError, quindi teoricamente non possono causare un OOME [*].

Un tipico esempio di caso d'uso consiste nel mantenere una forma analizzata di un contenuto da un file. Dovresti implementare un sistema in cui caricare un file, analizzarlo e mantenere un SoftReference sull'oggetto radice della rappresentazione analizzata. La prossima volta che avrai bisogno del file, proverai a recuperarlo tramite SoftReference. Se riesci a recuperarlo, ti sei risparmiato un altro carico / analisi e se il GC lo ha cancellato nel frattempo, lo ricarichi. In questo modo, utilizzi memoria libera per l'ottimizzazione delle prestazioni, ma non rischi un OOME.

Ora per il [*]. Mantenere un SoftReference non può causare un OOME in sé. Se d'altra parte si utilizza erroneamente SoftReference per un'attività che si intende utilizzare un WeakReference (vale a dire, mantenere le informazioni associate a un oggetto in qualche modo fortemente referenziate e scartarle quando l'oggetto di riferimento viene cancellato), è possibile eseguire OOME come il codice che esegue il polling di ReferenceQueue e scarta gli oggetti associati potrebbe non funzionare in modo tempestivo.

Quindi, la decisione dipende dall'uso - se stai memorizzando nella cache informazioni che sono costose da costruire, ma comunque ricostruibili da altri dati, usa riferimenti morbidi - se stai mantenendo un riferimento a un'istanza canonica di alcuni dati, o vuoi avere un riferimento a un oggetto senza "possederlo" (impedendogli così di essere GC'd), usare un riferimento debole.


14
Particolarmente utile per la spiegazione di quando verranno utilizzati oggetti deboli.
Jack BeNimble il

Un punto chiave sull'uso corretto di a WeakReferenceè che nei luoghi in cui si dovrebbe usarlo, il fatto che si possa rimanere validi per un po 'di tempo dopo che il riferimento esce dal campo di applicazione può essere tollerabile, ma non è desiderabile.
supercat,

Faccio fatica a capire a che serve WeakHashMap se produce sempre un riferimento debole al suo oggetto valore-chiave?

@supercat, C'è solo un uso corretto del WeakReferencequale è osservare le corse GC. Vedere elaborazione: stackoverflow.com/a/46291143/632951
Pacerier

1
@Pacerier: l'autore di quel post è semplicemente sbagliato. Trascura alcuni altri scenari di utilizzo come l'abbonamento ad eventi, il suo secondo punto è privo di senso e il suo terzo punto presuppone che un programmatore possa fare cose che potrebbero non essere possibili. Il suo primo punto è ragionevole, ma si collega direttamente a quello che ho detto. Se il codice dovrà spesso costruire e confrontare oggetti immutabili di grandi dimensioni, ad esempio, la parte di costruzione sarà spesso più economica se il codice crea nuovi oggetti senza considerare se esistono già, ma un confronto tra un oggetto e se stesso (riferimenti identici) sarà ...
supercat,

155

In Java ; nell'ordine dal più forte al più debole, ci sono: Forte, Morbido, Debole e Fantasma

Un riferimento forte è un riferimento normale che protegge l'oggetto indicato dalla raccolta da parte di GC. cioè non si raccoglie mai la spazzatura.

Un riferimento Soft può essere raccolto dal Garbage Collector, ma probabilmente non verrà raccolto fino a quando non sarà necessaria la sua memoria. cioè la spazzatura si raccoglie prima OutOfMemoryError.

Un riferimento debole è un riferimento che non protegge un oggetto referenziato dalla raccolta da parte di GC. cioè la spazzatura si raccoglie quando nessun riferimento forte o morbido.

Un riferimento Phantom è un riferimento a un oggetto a cui viene fatto un riferimento fantasma dopo che è stato finalizzato, ma prima che la sua memoria allocata sia stata recuperata.

fonte

Analogia: supponiamo che una JVM sia un regno, Object sia un re del regno e GC sia un attaccante del regno che cerca di uccidere il re (oggetto).

  • Quando King is Strong , GC non può ucciderlo.
  • Quando King è Soft , GC lo attacca ma King governa il regno con protezione fino a quando le risorse non sono disponibili.
  • Quando King è debole , GC lo attacca ma governa il regno senza protezione.
  • Quando il re è Phantom , GC lo ha già ucciso, ma il re è disponibile tramite la sua anima.

7
Il riferimento morbido ... until memory is availablenon ha senso. Intendi is eligible for collection by garbage collector, but probably won't be collected until its memory is needed for another use?
ToolmakerSteve

1
Sì, Garbage Collector non raccoglierà il riferimento fino a quando la memoria non sarà disponibile.
Premraj,

2
Mi piacciono le cose semplici spiegate, senza troppa bla bla bla +1 da parte mia!
Adelin,

3
Eccellente riassunto con esempio innovativo
Ravindra babu,


77

Riferimento debole http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html

Principio: weak reference è legato alla raccolta dei rifiuti. Normalmente, l'oggetto con uno o più referencenon sarà idoneo per la garbage collection.
Il principio di cui sopra non è applicabile quando lo è weak reference. Se un oggetto ha solo un riferimento debole con altri oggetti, è pronto per la garbage collection.

Diamo un'occhiata all'esempio seguente: Abbiamo un oggetto Mapcon cui Chiave fa riferimento a un oggetto.

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());

    }
}

Ora, durante l'esecuzione del programma, abbiamo realizzato emp = null. Tenere Mappremuto il tasto non ha senso qui com'è null. Nella situazione sopra, l'oggetto non viene raccolto.

WeakHashMap

WeakHashMapè uno in cui le voci ( key-to-value mappings) verranno rimosse quando non è più possibile recuperarle da Map.

Consentitemi di mostrare lo stesso esempio sopra con WeakHashMap

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());
    }
}

Uscita: Ha preso 20 calls to System.gc()a risultato aMap sizedi: 0.

WeakHashMapha solo riferimenti deboli alle chiavi, non riferimenti forti come altre Mapclassi. Ci sono situazioni che devi fare attenzione quando il valore o la chiave è fortemente referenziato anche se hai usato WeakHashMap. Questo può essere evitato avvolgendo l'oggetto in un WeakReference .

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");
    }
}

Riferimenti morbidi.

Soft Referenceè leggermente più forte di quel riferimento debole. Il riferimento software consente la raccolta dei rifiuti, ma chiede al garbage collector di cancellarlo solo se non ci sono altre opzioni.

Il garbage collector non raccoglie in modo aggressivo oggetti delicatamente raggiungibili come fa con quelli debolmente raggiungibili - invece raccoglie oggetti delicatamente raggiungibili solo se "ha bisogno" della memoria. I riferimenti morbidi sono un modo di dire al garbage collector, "Finché la memoria non è troppo stretta, mi piacerebbe tenere questo oggetto in giro. Ma se la memoria diventa davvero stretta, vai avanti e raccoglilo e mi occuperò con quello." Il garbage collector deve cancellare tutti i riferimenti software prima di poterlo lanciare OutOfMemoryError.


5
Si può ottenere un NullPointerExceptionin aMap.get().put(...).
xehpuk,

Il tuo primo esempio di HashMap sembra sbagliato. Quando fai "aMap.put (emp, val);" sia 'emp' che 'val' sono riferimenti forti. Internamente, viene creata una nuova variabile per contenere 'emp' e 'val' così quando si fa "emp = null;" stai solo annullando la variabile "emp", ma non la variabile internamente alla mappa hash (che contiene ancora l'oggetto Employee originale). Pertanto, la mappa hash conterrà ancora un forte riferimento a "emp" indipendentemente da ciò che si fa con la variabile "emp" all'esterno.
Tiago,

@Tiago. No. Presumibilmente con il "primo esempio" ti riferisci WeakHashMapall'esempio (poiché quello è il primo che sta dimostrando un comportamento debole). Guarda il documento per "WeakHashMap": "An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. " l'intero punto di usare WeakHashMap è che non devi dichiarare / passare un WeakReference; WeakHashMap lo fa per te, internamente. docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html
ToolmakerSteve

Sono state prese 0 chiamate a System.gc () per avere una dimensione di HashMap debole: 0 è l'output del secondo programma?
Adelin,

1
Per un altro esempio di WeakHashMapazione, con l'app di esempio che mostra come le voci vengono rimosse solo dopo l' esecuzione della garbage collection, vedere la mia risposta alla domanda, WeakHashMap è in continua crescita o cancella le chiavi della garbage? .
Basil Bourque,

50

L'unica vera differenza tra un riferimento debole e un riferimento debole è quella

il garbage collector utilizza algoritmi per decidere se recuperare o meno un oggetto delicatamente raggiungibile, ma recupera sempre un oggetto debolmente raggiungibile.


@ATorras, Samir. Ho ampliato su questa risposta qui: stackoverflow.com/a/46291143/632951
Pacerier

25

SoftReferenceè progettato per le cache. Quando viene rilevato che un WeakReferenceriferimento a un oggetto altrimenti non raggiungibile, verrà cancellato immediatamente. SoftReferencepuò essere lasciato così com'è. In genere esiste un algoritmo relativo alla quantità di memoria libera e al tempo impiegato per determinare se deve essere cancellato. L'attuale algoritmo di Sun è quello di cancellare il riferimento se non è stato utilizzato in tanti secondi quanti sono i megabyte di memoria libera sull'heap Java (configurabile, l'HotSpot del server controlla rispetto all'heap massimo possibile impostato da -Xmx). SoftReferences verrà cancellato prima che OutOfMemoryErrorvenga lanciato, se non diversamente raggiungibile.


9
Ma in Android non è consigliato per le cache developer.android.com/reference/java/lang/ref/…
Yaroslav Mytkalyk,

4
@DoctororDrive tbf la domanda riguardava java, non dalvik! :-P
fabspro

2
@YaroslavMytkalyk, Francamente, se Android vuole riscrivere il comportamento di una classe, dovrebbe usare il proprio spazio dei nomi, non java.lang. Un simile abuso di sinonimi non sta facendo nulla di buono.
Pacerier,

9

Questo articolo può essere di grande aiuto per comprendere riferimenti forti, morbidi, deboli e fantasma.


Per darti un riepilogo,

Se hai solo riferimenti deboli a un oggetto (senza riferimenti forti), l'oggetto verrà recuperato da GC nel ciclo GC immediatamente successivo.

Se si dispone solo di riferimenti software a un oggetto (senza riferimenti forti), l'oggetto verrà recuperato da GC solo quando JVM esaurisce la memoria.


Quindi puoi dire che i riferimenti forti hanno il potere supremo (non possono mai essere raccolti da GC)

I riferimenti software sono potenti rispetto ai riferimenti deboli (poiché possono sfuggire al ciclo GC fino a quando la memoria JVM esaurisce la memoria)

I riferimenti deboli sono persino meno potenti dei riferimenti deboli (in quanto non possono sfuggire a nessun ciclo GC e verranno recuperati se l'oggetto non ha altri riferimenti forti).


Analogia del ristorante

  • Cameriere - GC
  • Tu - Oggetto nell'heap
  • Area ristorante / spazio - Heap space
  • Nuovo cliente: nuovo oggetto che desidera un tavolo nel ristorante

Ora, se sei un cliente forte (analogo a un riferimento forte), anche se un nuovo cliente arriva nel ristorante o cosa succede, non lascerai mai il tuo tavolo (l'area della memoria nell'heap). Il cameriere non ha il diritto di dirti (o addirittura richiederti) di lasciare il ristorante.

Se sei un cliente soft (analogo al riferimento soft), quindi se un nuovo cliente arriva nel ristorante, il cameriere non ti chiederà di lasciare il tavolo a meno che non ci sia altro tavolo vuoto per accogliere il nuovo cliente. (In altre parole, il cameriere ti chiederà di lasciare il tavolo solo se entra un nuovo cliente e non è rimasto nessun altro tavolo per questo nuovo cliente)

Se sei un cliente debole (analogo al riferimento debole), il cameriere, a suo piacimento, può (in qualsiasi momento) chiederti di lasciare il ristorante: P


7

L'unica vera differenza

Come da documento , i riferimenti deboli allentati devono essere cancellati da un GC in esecuzione.

Come da documento , le SoftReferenze libere devono essere cancellate prima che venga lanciata OOM.

Questa è l'unica vera differenza. Tutto il resto non fa parte del contratto. (Presumo che gli ultimi documenti siano contrattuali.)

Le SoftReferences sono utili. Le cache sensibili alla memoria utilizzano SoftReferences, non WeakReferences.


L'unico uso corretto di WeakReference è osservare la corsa del GC. Puoi farlo creando un nuovo WeakReference il cui oggetto esce immediatamente dall'ambito, quindi prova a ottenere null da weak_ref.get(). Quando è null, impari che tra questa durata, il GC ha funzionato.

Per quanto riguarda l' uso errato di WeakReference, l'elenco è infinito:

  • un trucco pessimo per implementare il softreference di priorità 2 in modo tale da non doverne scrivere uno, ma non funziona come previsto perché la cache verrebbe cancellata ad ogni esecuzione di GC, anche quando c'è memoria libera. Vedi https://stackoverflow.com/a/3243242/632951 per phails. (Inoltre, cosa succede se hai bisogno di più di 2 livelli di priorità della cache? Dovresti comunque avere bisogno di una vera libreria per questo.)

  • un trucco pessimo per associare i dati a un oggetto di una classe esistente, ma crea una perdita di memoria (OutOfMemoryError) quando il tuo GC decide di fare una pausa dopo la creazione dei tuoi riferimenti deboli. Inoltre, è al di là del brutto: un approccio migliore è usare le tuple.

  • un trucco scadente per associare i dati a un oggetto di una classe esistente, in cui la classe ha il coraggio di rendersi non classificabile e viene utilizzata in un codice di funzione esistente che è necessario chiamare. In tal caso, la soluzione corretta consiste nel modificare la classe e renderla sottoclassabile, oppure modificare la funzione e far sì che prenda un'interfaccia anziché una classe, oppure usi una funzione alternativa.


Che dire di una cache in cui il tipo di chiave equals()è solo l'identità dell'oggetto? I riferimenti morbidi sembrano uno spreco lì, perché una volta che un oggetto chiave non è più fortemente raggiungibile, nessuno potrà mai più cercare quella mappatura.
HighCommander4,

Non sono d'accordo. Usa WeakReference quando non vuoi influenzare GC in alcun modo (potresti voler salvare un riferimento a un oggetto e poi verificare se esiste ancora, senza alcuna preferenza). Utilizzare SoftReference se si desidera influenzare il GC per provare a conservare l'oggetto (ovvero quando si preferisce che il GC lo conservi).
David Refaeli,

Un buon esempio di come utilizzare WeakReference è in AsyncTask di Android - per mantenere un'istanza del contesto. In questo modo se il contesto muore (se l'attività - rotazione dello schermo, ecc.), L'AsyncTask non avrà alcun riferimento forte ad esso, e quindi può essere raccolto. Controlla youtu.be/…
David Refaeli il

3

I sei tipi di stati di raggiungibilità degli oggetti in Java:

  1. Forti oggetti ly raggiungibili - GC non saranno collect ( recuperare la memoria occupata da ) questo tipo di oggetto. Questi sono raggiungibili tramite un nodo radice o un altro oggetto fortemente raggiungibile (ovvero tramite variabili locali, variabili di classe, variabili di istanza, ecc.)
  2. Morbido ly oggetti raggiungibili - GC possono tentare di raccogliere questo tipo di oggetto a seconda contesa memoria. Questi sono raggiungibili dalla radice tramite uno o più oggetti di riferimento soft
  3. Oggetti deboli raggiungibili - GC deve raccogliere questo tipo di oggetto. Questi sono raggiungibili dalla radice tramite uno o più oggetti di riferimento deboli
  4. Oggetti capaci di resurrezione : GC sta già raccogliendo questi oggetti. Ma possono tornare a uno degli stati - Forte / Morbido / Debole mediante l'esecuzione di alcuni finalizzatori
  5. Phantom ly raggiungable object - GC sta già raccogliendo questi oggetti e ha deciso di non essere in grado di resuscitare da alcun finalizzatore (se dichiara un metodo finalize () stesso, allora il suo finalizzatore sarà stato eseguito) . Questi sono raggiungibili dalla radice tramite uno o più oggetti di riferimento fantasma
  6. Oggetto irraggiungibile : un oggetto non è raggiungibile in modo forte, dolcemente, debolmente o fantasma e non è resurrible. Questi oggetti sono pronti per il recupero

Per maggiori dettagli: https://www.artima.com/insidejvm/ed2/gc16.html «collapse


4
Non è una buona descrizione di riferimenti fantasma. Inoltre, hai elencato i 4 tipi in un ordine particolare. "fantasma" è il tipo più debole, non il tipo più forte. L'ordine tradizionale di elencarli è "forte, morbido, debole, fantasma". E non ho idea di dove tu abbia avuto l'idea che gli oggetti fantasma sono usati per i meccanismi di memorizzazione nella cache. AFAIK, sono uno stato temporaneo visto solo dal GC, non qualcosa con cui un normale programmatore avrebbe lavorato.
ToolmakerSteve

@ToolmakerSteve e tutti - Scuse per un paio di cose 1. la spiegazione errata dei riferimenti Phantom nella versione precedente della mia risposta, e 2. Ritardo nella correzione degli errori. Ora la risposta è stata migliorata correggendo gli errori
V.Vidyasagar,

1

Bisogna essere consapevoli che un oggetto debolmente referenziato verrà raccolto solo quando ha SOLO riferimenti deboli. Se ha un riferimento forte, non viene raccolto, indipendentemente da quanti riferimenti deboli ha.


Questo è buon senso ... lo stesso vale per softref e phantomref.
Pacerier,

1

Per dare un aspetto all'utilizzo della memoria in azione, ho fatto un esperimento con riferimenti Strong, Soft, Weak & Phantom sotto carico pesante con oggetti pesanti, conservandoli fino alla fine del programma. Quindi monitorato l'utilizzo dell'heap e il comportamento GC . Queste metriche possono variare caso per caso, ma offrono sicuramente una comprensione di alto livello. Di seguito sono riportati i risultati.

Comportamento di heap e GC sotto carico pesante

  • Riferimento forte / difficile: man mano che il programma continuava, JVM non riusciva a raccogliere oggetti con riferimento forte conservati. Alla fine è finito in "java.lang.OutOfMemoryError: spazio heap Java"
  • Riferimento morbido - Mentre il programma continuava, l'utilizzo dell'heap continuava a crescere, ma il GC di vecchia generazione si è verificato quando stava per raggiungere l'heap massimo. GC è iniziato poco dopo l'avvio del programma.
  • Riferimento debole : all'avvio del programma, gli oggetti hanno iniziato a essere finalizzati e raccolti quasi immediatamente. Per lo più oggetti sono stati raccolti nella raccolta dei rifiuti di nuova generazione.
  • Riferimento fantasma - Simile al riferimento debole, anche gli oggetti referenziati fantasma hanno iniziato a essere finalizzati e la raccolta dei rifiuti immediatamente. Non esistevano GC di vecchia generazione e tutti gli oggetti venivano raccolti nella stessa raccolta di rifiuti di nuova generazione.

Puoi ottenere grafici più approfonditi , statistiche, osservazioni per questo esperimento qui .


0

WeakReference : gli oggetti a cui viene fatto solo un riferimento debole vengono raccolti in ogni ciclo GC (minore o completo).

SoftReference : quando vengono raccolti oggetti a cui viene fatto solo un leggero riferimento dipende da:

  1. -XX: SoftRefLRUPolicyMSPerMB = flag N (il valore predefinito è 1000, ovvero 1 secondo)

  2. Quantità di memoria libera nell'heap.

    Esempio:

    • heap ha 10 MB di spazio libero (dopo GC completo);
    • -XX: SoftRefLRUPolicyMSPerMB = 1000

    Quindi l'oggetto a cui fa riferimento solo SoftReference verrà raccolto se l'ultima volta in cui è stato effettuato l'accesso è maggiore di 10 secondi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.