Références fantômes en Java

Références fantômes en Java

1. Vue d'ensemble

Dans cet article, nous allons examiner le concept de référence fantôme - dans le langage Java.

2. Références fantômes

Les références fantômes présentent deux différences majeures par rapport aux référencessoft etweak.

We can’t get a referent of a phantom reference. Le référent n'est jamais accessible directement via l'API et c'est pourquoi nous avons besoin d'une file d'attente de références pour travailler avec ce type de références.

Le garbage collector ajoute une référence fantôme à une file d'attente de référenceafter the finalize method of its referent is executed. Cela implique que l'instance est toujours dans la mémoire.

3. Cas d'utilisation

Ils sont utilisés pour deux cas d'utilisation courants.

La première technique estto determine when an object was removed from the memory qui permet de planifier des tâches sensibles à la mémoire. Par exemple, nous pouvons attendre qu'un objet volumineux soit supprimé avant d'en charger un autre.

La deuxième pratique estto avoid using the finalize method and improve thefinalization process.

3.1. Exemple

Maintenant, implémentons le deuxième cas d'utilisation pour comprendre pratiquement comment ce type de références fonctionne.

Tout d'abord, nous avons besoin d'une sous-classe de la classePhantomReference pour définir une méthode d'effacement des ressources:

public class LargeObjectFinalizer extends PhantomReference {

    public LargeObjectFinalizer(
      Object referent, ReferenceQueue q) {
        super(referent, q);
    }

    public void finalizeResources() {
        // free resources
        System.out.println("clearing ...");
    }
}


Nous allons maintenant écrire une mise au point améliorée:

ReferenceQueue referenceQueue = new ReferenceQueue<>();
List references = new ArrayList<>();
List largeObjects = new ArrayList<>();

for (int i = 0; i < 10; ++i) {
    Object largeObject = new Object();
    largeObjects.add(largeObject);
    references.add(new LargeObjectFinalizer(largeObject, referenceQueue));
}

largeObjects = null;
System.gc();

Reference referenceFromQueue;
for (PhantomReference reference : references) {
    System.out.println(reference.isEnqueued());
}

while ((referenceFromQueue = referenceQueue.poll()) != null) {
    ((LargeObjectFinalizer)referenceFromQueue).finalizeResources();
    referenceFromQueue.clear();
}


Tout d'abord, nous initialisons tous les objets nécessaires:referenceQueue - pour garder une trace des références mises en file d'attente,references - pour effectuer un travail de nettoyage par la suite,largeObjects - pour imiter une grande structure de données.

Ensuite, nous créons ces objets en utilisant les classesObject etLargeObjectFinalizer.

Avant d'appeler le Garbage Collector, nous libérons manuellement un gros morceau de données en déréférençant la listelargeObjects. Notez que nous avons utilisé un raccourci pour l'instructionRuntime.getRuntime().gc() pour appeler le garbage collector.

Il est important de savoir queSystem.gc() ne déclenche pas le nettoyage de la mémoire immédiatement - il s’agit simplement d’un indice pour que JVM déclenche le processus.

La bouclefor montre comment s'assurer que toutes les références sont mises en file d'attente - elle afficheratrue pour chaque référence.

Enfin, nous avons utilisé une bouclewhile pour interroger les références mises en file d'attente et effectuer un travail de nettoyage pour chacune d'elles.

4. Conclusion

Dans ce rapide didacticiel, nous avons présenté les références fantômes de Java.

Nous avons appris en quoi ils consistent et comment ils peuvent être utiles dans des exemples simples et pertinents.