La seule chose que je sais PhantomReference
est,
- Si vous utilisez sa
get()
méthode, elle retournera toujoursnull
et non l'objet. Quelle en est l'utilité? - En utilisant
PhantomReference
, vous vous assurez que l'objet ne peut pas être ressuscité à partir definalize
method.
Mais à quoi sert ce concept / cette classe?
Avez-vous déjà utilisé cela dans l'un de vos projets ou avez-vous un exemple où nous devrions l'utiliser?
FakeReference
ouNonReference
.Réponses:
J'ai utilisé
PhantomReference
s dans un type de profileur de mémoire simpliste et très spécialisé pour surveiller la création et la destruction d'objets. J'avais besoin d'eux pour suivre la destruction. Mais l'approche est dépassée. (Il a été écrit en 2004 pour J2SE 1.4.) Les outils de profilage professionnels sont beaucoup plus puissants et fiables et les nouvelles fonctionnalités Java 5 comme JMX ou les agents et JVMTI peuvent également être utilisées pour cela.PhantomReference
s (toujours utilisé avec la file d'attente de référence) sont supérieurs à ceuxfinalize
qui posent certains problèmes et doivent donc être évités. Principalement rendre les objets accessibles à nouveau. Cela pourrait être évité avec l'idiome du gardien du finaliseur (-> en savoir plus dans 'Effective Java'). Donc, ils sont aussi les nouveaux finaliser .En outre,
PhantomReference
sEt comme psd l'a écrit en premier, Roedy Green a un bon résumé des références .
la source
Une explication générale de la table en dés , tirée du glossaire Java.
Ce qui coïncide bien sûr avec la documentation PhantomReference :
Et le dernier mais non le moindre, tous les détails sanglants ( c'est une bonne lecture ): Objets de référence Java (ou comment j'ai appris à arrêter de m'inquiéter et à aimer OutOfMemoryError) .
Bon codage. (Mais pour répondre à la question, je n'ai jamais utilisé que des références faibles.)
la source
Excellente explication de l'utilisation de Phantom Reference:
la source
J'ai trouvé un cas d'utilisation pratique et utile
PhantomReference
qui estorg.apache.commons.io.FileCleaningTracker
dans le projet commons-io.FileCleaningTracker
supprimera le fichier physique lorsque son objet marqueur sera récupéré.Quelque chose à noter est la
Tracker
classe qui étend laPhantomReference
classe.la source
CELA DEVRAIT ÊTRE OBSOLÉ AVEC JAVA 9!
Utilisez
java.util.Cleaner
plutôt! (Ousun.misc.Cleaner
sur un JRE plus ancien)Message d'origine:
J'ai trouvé que l'utilisation de PhantomReferences a presque le même nombre de pièges que les méthodes de finalisation (mais moins de problèmes une fois que vous avez bien fait les choses). J'ai écrit une petite solution (un très petit framework pour utiliser PhantomReferences) pour Java 8. Cela permet d'utiliser des expressions lambda comme rappels à exécuter après la suppression de l'objet. Vous pouvez enregistrer les rappels pour les ressources internes qui doivent être fermées. Avec cela, j'ai trouvé une solution qui fonctionne pour moi car elle la rend beaucoup plus pratique.
https://github.com/claudemartin/java-cleanup
Voici un petit exemple pour montrer comment un rappel est enregistré:
Et puis il y a la méthode encore plus simple pour la fermeture automatique, faisant à peu près la même chose que ci-dessus:
Pour répondre à tes questions:
Vous ne pouvez pas nettoyer quelque chose qui n'existe pas. Mais il aurait pu avoir des ressources qui existent toujours et doivent être nettoyées pour pouvoir être supprimées.
Il ne s'agit pas nécessairement de faire quoi que ce soit avec un effet autre que le débogage / la journalisation. Ou peut-être pour les statistiques. Je le vois plus comme un service de notification du GC. Vous pouvez également l'utiliser pour supprimer les données agrégées qui deviennent inutiles une fois l'objet supprimé (mais il existe probablement de meilleures solutions pour cela). Les exemples mentionnent souvent que les connexions à la base de données doivent être fermées, mais je ne vois pas en quoi c'est une si bonne idée que vous ne pouvez pas travailler avec des transactions. Un cadre d'application fournira une bien meilleure solution pour cela.
Je l'utilise principalement pour la journalisation. Je peux donc retracer les éléments supprimés et voir comment GC fonctionne et peut être modifié. Je n'exécuterais aucun code critique de cette manière. Si quelque chose doit être fermé, cela doit être fait dans une instruction try-with-resource. Et je l'utilise dans les tests unitaires, pour m'assurer de ne pas avoir de fuites de mémoire. De la même manière que jontejj le fait. Mais ma solution est un peu plus générale.
la source
J'ai utilisé un PhantomReference dans un test unitaire pour vérifier que le code sous test ne gardait pas de références indésirables à un objet. ( Code d'origine )
Et le test :
la source
Il est courant d'utiliser
WeakReference
là oùPhantomReference
c'est plus approprié. Cela évite certains problèmes de pouvoir ressusciter des objets après unWeakReference
est effacé / mis en file d'attente par le garbage collector. Habituellement, la différence n'a pas d'importance parce que les gens ne jouent pas à des buggers stupides.L'utilisation a
PhantomReference
tendance à être un peu plus intrusive car vous ne pouvez pas prétendre que laget
méthode fonctionne. Vous ne pouvez pas, par exemple, écrire un fichierPhantom[Identity]HashMap
.la source
weakref.get
pourrait revenirnull
, et plus tard, il est toujours en mesure de retourner l'objet?finalize
ne recrée pas l'objet en tant que tel. Il peut rendre l'objet à nouveau fortement accessible après unWeakReference
retournull
deget
et mis en file d'attente. / (user166390: Comme dans une carte saisie sur la cible de la référence, comme leWeakHashMap
fait, pas une carte d'identité de références ce qui est bien.)Les méthodes utiles pour appeler (plutôt que
get()
) seraientisEnqueued()
oureferenceQueue.remove()
. Vous appelleriez ces méthodes pour effectuer une action qui doit avoir lieu lors du dernier tour de garbage collection de l'objet.La première fois, c'est lorsque l'objet a sa
finalize()
méthode appelée, vous pouvez donc y placer des crochets de fermeture. Cependant, comme d'autres l'ont indiqué, il existe probablement des moyens plus sûrs d'effectuer le nettoyage ou toute autre action qui doit avoir lieu avant et après le ramassage des ordures ou, plus généralement, à la fin de la vie de l'objet.la source
J'ai trouvé une autre utilisation pratique de
PhantomReferences
dans la classe LeakDetector de Jetty.Jetty utilise la
LeakDetector
classe pour détecter si le code client acquiert une ressource mais ne la libère jamais et laLeakDetector
classe utilise lePhantomReferences
à cette fin.la source