8.1 Références faibles en Java
Il existe plusieurs types de références en Java.
Il y a StrongReference - ce sont les liens les plus courants que nous créons chaque jour.
Object object = new Object();//created an object
object = null;//can now be garbage collected
Et il existe trois types de liens "spéciaux" - SoftReference, WeakReference, PhantomReference. En fait, il n'y a qu'une seule différence entre tous les types de liens - le comportement du GC avec les objets auxquels ils se réfèrent. Nous discuterons des spécificités de chaque type de lien plus en détail plus tard, mais pour l'instant, les connaissances suivantes suffiront :
- SoftReference est une référence logicielle, si le GC voit qu'un objet n'est accessible que via une chaîne de références logicielles, il le supprimera de la mémoire. Peut être.
- WeakReference - une référence faible, si le GC voit qu'un objet n'est accessible que par une chaîne de références faibles, il le supprimera de la mémoire.
- PhantomReference est une référence fantôme, si le GC voit qu'un objet n'est disponible que via une chaîne de références fantômes, il le supprimera de la mémoire. Après plusieurs passages de GC.
Vous pouvez également dire que les types de liens ont un certain degré de douceur :
- Un lien dur régulier est une variable d'un type de référence. Non nettoyé par le ramasse-miettes avant qu'il ne devienne inutilisé.
- SoftReference . L'objet n'entraînera pas l'utilisation de toute la mémoire - il est garanti qu'il sera supprimé avant qu'une OutOfMemoryError ne se produise. Peut-être plus tôt, selon l'implémentation du ramasse-miettes.
- Référencefaible . Doux plus faible. N'empêche pas la suppression de l'objet ; le ramasse-miettes ignore ces références.
- PhantomReference . Utilisé pour le traitement de "mort" d'un objet : l'objet est disponible après finalisation jusqu'à ce qu'il soit ramassé.
Si la différence n'est pas encore claire, ne vous inquiétez pas, bientôt tout se mettra en place. Les détails sont dans les détails, et les détails suivront.
8.2 WeakReference et SoftReference en Java
Voyons d'abord la différence entre WeakReference et SoftReference en Java.
En bref, le ramasse-miettes libérera la mémoire d'un objet si seules des références faibles pointent vers lui. Si l'objet est pointé par SoftReferences, la mémoire est désallouée lorsque la JVM a un besoin urgent de mémoire.
Cela donne un avantage certain à SoftReference par rapport à Strong reference dans certains cas. Par exemple, SoftReference est utilisé pour implémenter un cache d'application, donc la première chose que fera la JVM est de supprimer les objets vers lesquels pointent uniquement SoftReferences.
WeakReference est idéal pour stocker des métadonnées, telles que le stockage d'une référence à un ClassLoader. Si aucune classe n'est chargée, vous ne devez pas vous référer au ClassLoader. C'est pourquoi WeakReference permet au ramasse-miettes de faire son travail sur le ClassLoader dès que la dernière référence forte à celui-ci est supprimée.
Exemple de WeakReference en 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;
Exemple SoftReference en 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 PhantomReference en Java
L'instance PhantomReference est créée de la même manière que dans les exemples WeakReference et SoftReference, mais elle est rarement utilisée.
Une PhantomReference peut être ramassée si l'objet n'a pas de références fortes (Strong), faibles (WeakReference) ou souples (SoftReference).
Vous pouvez créer un objet Phantom Reference comme ceci :
PhantomReference myObjectRef = new PhantomReference(MyObject);
PhantomReference peut être utilisé dans des situations où finalize() n'a pas de sens. Ce type de référence est différent des autres types car il n'est pas conçu pour accéder à un objet. C'est un signal que l'objet a déjà été finalisé et que le ramasse-miettes est prêt à récupérer sa mémoire.
Pour ce faire, le ramasse-miettes le place dans une file d'attente de référence spéciale pour un traitement ultérieur. ReferenceQueue est l'endroit où les références d'objets sont placées pour libérer de la mémoire.
Les références fantômes sont un moyen sûr de savoir qu'un objet a été supprimé de la mémoire. Par exemple, considérez une application qui traite de grandes images. Disons que nous voulons charger une image en mémoire alors qu'elle est déjà en mémoire, qui est prête pour la récupération de place. Dans ce cas, nous voulons attendre que le ramasse-miettes tue l'ancienne image avant de charger la nouvelle image en mémoire.
Ici, PhantomReference est un choix flexible et sûr. La référence à l'ancienne image sera transmise à la ReferenceQueue après la destruction de l'ancien objet image. Une fois que nous avons ce lien, nous pouvons charger la nouvelle image en mémoire.