Voici la suite et la fin des articles sur les références Java consacré aux PhantomReferences.
Ces dernières sont très différentes des Weak et Soft Reference. Tout d’abord, tout appel à la méthode get() d’une PhantomReference retournera null.
Pourquoi ? Car les PhantomReference sont utilisées pour référencer des objets « presque morts », et vous ne devez donc pas pouvoir les ressusciter !
Concrètement, les PhantomReference sont utilisées pour détecter la suppression d’un objet en mémoire. Leur utilisation est même préférable à l’utilisation de la méthode finalize() (qui a le fâcheux effet de bord de permettre la résurrection des objets).
Voici le constructeur des PhantomReferences :
PhantomReference(Object referent, ReferenceQueue q);
On constate un paramètre supplémentaire par rapport aux autres références : la ReferenceQueue.
L’intérêt de ce paramètre est de fournir une liste des objets libérés par le garbage collector. Vous pouvez ainsi déterminer quand un objet a été libéré (et exécuter ensuite votre propre libération de ressources, par exemple).
Exemple :
// On alloue 1 objet, par exemple une chaîne
String test = "toto";
// Création de la file et de la référence
ReferenceQueue queue = new ReferenceQueue();
PhantomReference ref = new PhantomReference(test, queue);
System.out.println(test);
// On libère l'objet
test = null;
boolean fin = false;
// Et on attend la libération
while (!fin) {
// Demande de référence avec attente d'une seconde max
Reference phantRef = queue.remove(1000);
if (phantRef == ref) {
System.out.println("Objet libéré");
fin = true;
}
[...]
}
Salut,
Petite remarque : la ReferenceQueue peut également être utilisée avec les références Weak et Soft ! Cela peut permettre de gérer un cache et de supprimer les références vides…
a++
Retrouvez cet article sur Blogasty …
Vous aimez cet article? Votez pour lui sur Blogasty …
Au sujet de cette ligne de code:
String test = « toto »;
Cet objet ne sera jamais collecté par le GC, car il pointe sur un objet statique (la String « toto »). L’objet ne peut donc pas être collecté. Le GC est destiné à nettoyer les objets créés dynamiquement dans le Heap. Pour éviter une boucle infinie, il faudrait plutôt écrire:
String test = new String(« toto »);
La commande « new » réservera l’espace pour un objet String dans le Heap et la chaîne « toto » y sera ensuite recopiée.
Très bon article par ailleurs.
Bonne remarque, merci !!
Par contre, je me demande si ce comportement ne dépend pas de l’implémentation de la JVM, je regarderai à l’occasion.