Skip to content

Java, PhantomReference et finalize()

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;
}
[...]
}

Published inProgrammation
Loading Facebook Comments ...

4 Comments

  1. 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++

  2. Retrouvez cet article sur Blogasty …

    Vous aimez cet article? Votez pour lui sur Blogasty …

  3. ruste ruste

    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.

    • Gerben CASTEL Gerben CASTEL

      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.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.