8.1 Riferimenti deboli in Java
Esistono diversi tipi di riferimenti in Java.
C'è StrongReference : questi sono i collegamenti più comuni che creiamo ogni giorno.
Object object = new Object();//created an object
object = null;//can now be garbage collected
E ci sono tre tipi di collegamenti "speciali": SoftReference, WeakReference, PhantomReference. In effetti, c'è solo una differenza tra tutti i tipi di collegamenti: il comportamento del GC con gli oggetti a cui si riferiscono. Discuteremo le specifiche di ciascun tipo di collegamento in modo più dettagliato in seguito, ma per ora sarà sufficiente la seguente conoscenza:
- SoftReference è un riferimento soft, se il GC vede che un oggetto è accessibile solo attraverso una catena di riferimenti soft, lo rimuoverà dalla memoria. Forse.
- WeakReference - un riferimento debole, se il GC vede che un oggetto è accessibile solo attraverso una catena di riferimenti deboli, lo rimuoverà dalla memoria.
- PhantomReference è un riferimento fantasma, se il GC vede che un oggetto è disponibile solo attraverso una catena di riferimenti fantasma, lo rimuoverà dalla memoria. Dopo diverse corse di GC.
Puoi anche dire che i tipi di collegamento hanno un certo grado di morbidezza:
- Un hard link regolare è qualsiasi variabile di un tipo di riferimento. Non ripulito dal Garbage Collector prima che diventi inutilizzato.
- SoftReference . L'oggetto non causerà l'esaurimento di tutta la memoria: è garantito che venga eliminato prima che si verifichi un OutOfMemoryError. Forse prima, a seconda dell'implementazione del Garbage Collector.
- Riferimento debole . Più debole morbido. Non impedisce l'eliminazione dell'oggetto; il Garbage Collector ignora tali riferimenti.
- Riferimento fantasma . Utilizzato per l'elaborazione "morte" di un oggetto: l'oggetto è disponibile dopo la finalizzazione fino a quando non viene sottoposto a Garbage Collection.
Se non è ancora chiaro quale sia la differenza, non preoccuparti, presto tutto andrà a posto. I dettagli sono nei dettagli e i dettagli seguiranno.
8.2 WeakReference e SoftReference in Java
Innanzitutto, diamo un'occhiata alla differenza tra WeakReference e SoftReference in Java.
In breve, il Garbage Collector libererà la memoria di un oggetto se solo riferimenti deboli lo puntano. Se l'oggetto è puntato da SoftReferences, la memoria viene deallocata quando la JVM ha un disperato bisogno di memoria.
Ciò offre un netto vantaggio a SoftReference rispetto a Strong reference in alcuni casi. Ad esempio, SoftReference viene utilizzato per implementare una cache dell'applicazione, quindi la prima cosa che farà JVM è eliminare gli oggetti a cui puntano solo SoftReferences.
WeakReference è ottimo per l'archiviazione di metadati, come l'archiviazione di un riferimento a un ClassLoader. Se non viene caricata alcuna classe, non dovresti fare riferimento a ClassLoader. Questo è il motivo per cui WeakReference consente al Garbage Collector di svolgere il proprio lavoro sul ClassLoader non appena viene rimosso l'ultimo riferimento forte ad esso.
Esempio di WeakReference in Java:
// some object
Student student = new Student();
// weak reference to it
WeakReference
weakStudent
=
new
WeakReference
(student
)
;
// now the Student object can be garbage collected student
=
null
;
Esempio di SoftReference in Java:
// some object
Student student = new Student();
// weak reference to it
SoftReference
softStudent
=
new
SoftReference
(student
)
// now the Student object can be garbage collected
// but this will only happen if the JVM has a strong need for memory student
=
null
;
8.3 Riferimento fantasma in Java
L'istanza PhantomReference viene creata nello stesso modo degli esempi WeakReference e SoftReference, ma viene utilizzata raramente.
Un PhantomReference può essere sottoposto a Garbage Collection se l'oggetto non dispone di riferimenti forti (Strong), deboli (WeakReference) o soft (SoftReference).
Puoi creare un oggetto di riferimento fantasma come questo:
PhantomReference myObjectRef = new PhantomReference(MyObject);
PhantomReference può essere utilizzato in situazioni in cui finalize() non ha senso. Questo tipo di riferimento è diverso dagli altri tipi perché non è progettato per accedere a un oggetto. È un segnale che l'oggetto è già stato finalizzato e il Garbage Collector è pronto a recuperare la sua memoria.
Per fare ciò, il Garbage Collector lo inserisce in una speciale ReferenceQueue per un'ulteriore elaborazione. ReferenceQueue è il punto in cui vengono posizionati i riferimenti agli oggetti per liberare memoria.
I riferimenti fantasma sono un modo sicuro per sapere che un oggetto è stato rimosso dalla memoria. Ad esempio, considera un'applicazione che si occupa di immagini di grandi dimensioni. Supponiamo di voler caricare un'immagine in memoria quando è già in memoria, che è pronta per la raccolta dei rifiuti. In questo caso, vogliamo aspettare che il Garbage Collector elimini la vecchia immagine prima di caricare la nuova immagine in memoria.
Qui PhantomReference è una scelta flessibile e sicura. Il riferimento alla vecchia immagine verrà passato a ReferenceQueue dopo che il vecchio oggetto immagine è stato distrutto. Una volta che abbiamo questo collegamento, possiamo caricare la nuova immagine in memoria.
GO TO FULL VERSION