Quelqu'un peut-il expliquer la différence entre les trois classes de référence (ou poster un lien vers une explication de Nice)? SoftReference
> WeakReference
> PhantomReference
, mais quand utiliserais-je chacun d'eux? Pourquoi y a-t-il une WeakHashMap
mais pas SoftHashMap
ou PhantomHashMap
?
Et si j'utilise le code suivant ...
WeakReference<String> ref = new WeakReference<String>("Hello!");
if (ref != null) { // ref can get collected at any time...
System.gc(); // Let's assume ref gets collected here.
System.out.println(ref.get()); // Now what?!
}
...ce qui se produit? Dois-je vérifier si ref
est nul avant chaque déclaration (c'est faux, mais que devrait je fais)? Désolé pour les questions à réponse rapide, mais j'ai du mal à comprendre ces classes Reference
... Merci!
La bibliothèque Java documentation du package Java.lang.ref
caractérise la force décroissante des trois types de référence explicites.
Vous utilisez un SoftReference
lorsque vous souhaitez que l'objet référencé reste en vie jusqu'à ce que le processus de l'hôte manque de mémoire. L'objet ne sera pas éligible à la collecte tant que le collecteur n'aura pas besoin de libérer de la mémoire. Lâchement déclaré, lier un SoftReference
signifie: "Épinglez l'objet jusqu'à ce que vous ne puissiez plus."
En revanche, utilisez un WeakReference
lorsque vous ne souhaitez pas influencer la durée de vie de l'objet référencé; vous voulez simplement faire une assertion séparée à propos de l'objet référencé, tant qu'il reste en vie. L'éligibilité de l'objet à la collecte n'est pas influencée par la présence de WeakReference
s liés. Quelque chose comme un mappage externe d'une instance d'objet à une propriété associée, où la propriété doit uniquement être enregistrée tant que l'objet associé est en vie, est une bonne utilisation de WeakReference
s et WeakHashMap
.
Le dernier —PhantomReference
— est plus difficile à caractériser. Comme WeakReference
, un tel lien PhantomReference
n'exerce aucune influence sur la durée de vie de l'objet référencé. Mais contrairement aux autres types de référence, on ne peut même pas déréférencer un PhantomReference
. En un sens, cela ne pointe pas vers ce qui est indiqué, pour autant que les appelants puissent le savoir. Cela permet simplement d'associer des données liées à l'objet référencé - des données qui peuvent ensuite être inspectées et traitées lorsque le PhantomReference
est mis en file d'attente dans son objet ReferenceQueue
associé. Normalement, on dérive un type de PhantomReference
et inclut des données supplémentaires dans ce type dérivé. Malheureusement, il y a un certain déclin à faire pour utiliser un tel type dérivé.
Dans votre exemple de code, ce n'est pas la référence ref
(ou, si vous préférez, "variable") qui peut être null. C'est plutôt la valeur obtenue en appelant Reference#get()
qui peut être null. Si cela s'avère nul, vous êtes trop tard; l'objet référencé est déjà sur le point d'être collecté:
final String val = ref.get();
if (null != val)
{
// "val" is now pinned strongly.
}
else
{
// "val" is already ready to be collected.
}
Un lien: https://community.Oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references
PhantomHashMap
ne fonctionnerait pas très bien car get
renvoie toujours null
pour les références fantômes.
Les caches sont difficiles, donc SoftHashMap
pourrait ne pas fonctionner aussi bien que vous le pensez. Cependant, je pense que la bibliothèque de collections de Google contient une implémentation générale de la carte de référence.
Vous devriez toujours vérifier que get
renvoie une variable non -null
. (Notez que ne pas vérifier que la référence Reference
elle-même n'est pas -null
.) Dans le cas de chaînes internées, cela le sera toujours, mais (comme toujours) n'essayez pas d'être "intelligent" à ce sujet.
Il convient également de mentionner, comme indiqué dans le commentaire de Truong Xuan Tinh, ici: http://blog.yohanliyanage.com/2010/10/ktjs-3-soft-weak-phantom-references/
Cette machine virtuelle Java de JRockit implémente les références faibles/douces/fantômes de manière différente de celle de Sun JVM.
String str = new String("hello, world");
WeakReference<String> ref = new WeakReference<String>(str);
str = null;
if (ref != null) {
System.gc();
System.out.println(ref.get());
}
Dans ce cas, la sortie sera nulle. L'appel à System.gc()
est important ici.