Pour répondre à la deuxième partie d'abord, un objet Class
est uniquement éligible pour la collecte des ordures lorsque le Classloader
responsable est à son tour ramassé à la poubelle. Voir Section 12.7 of the JLS:
Une classe ou de l'interface peuvent être déchargées si et seulement si son chargeur de classe peut être récupéré définition par le collecteur des ordures comme indiqué dans § 12.6. Les classes et interfaces chargées par le chargeur d'amorçage ne peuvent pas être déchargées.
Ainsi, un WeakReference<Class>
est probablement pas susceptible de faire ce que vous espérez (bien que ce n'est pas 100% clair pour moi ce que vous sont recherche).
Maintenant, revenons à la première partie - avez-vous besoin d'un HashSet faible? Cela dépend, encore une fois, de ce que vous essayez de faire. Si vous voulez que les entrées Map
soient récupérées quand la valeur Set
elle-même n'est plus référencée, non, vous n'avez pas besoin d'un faible HashMap
. (google-collections utilise la référence d'égalité pour les valeurs et clés faiblement référencées, d'ailleurs, il n'y a donc pas de problèmes d'égalité difficiles ici). Après la suppression de la dernière référence au Set
GC, l'entrée Map
sera récupérée.
Notez également que cela permettra aux Foo
d'être également collectés dans les ordures; Une fois que vous avez supprimé la référence au Set<Foo>
, les Foo
ne sont que faiblement accessibles et peuvent être ignorés. Voir the Javadoc for java.lang.ref package:
Un objet est fortement accessible s'il peut être atteint par un thread sans passer par les objets de référence. [...] Un objet est faiblement accessible s'il n'est ni fortement ni doucement accessible mais peut être atteint en traversant une référence faible. Lorsque les références faibles à un objet faiblement accessible sont effacées, l'objet devient éligible à la finalisation.
Donc, si la seule chaîne de référence est (forte référence à Map
) → (Map
tient référence faible à Set
) → (Set
référence à forte tient Foo
), le Foo
peut être collecté les déchets.
Cependant, j'ai un soupçon lancinante ce n'est pas ce que vous recherchez. Je soupçonne que ce que vous voulez, c'est que l'entrée Map soit récupérée lorsque le dernier Foo
n'est plus référencé; que vous ne détenez pas de référence au Set<Foo>
lui-même, mais plutôt aux objets individuels Foo
.
Si c'est le cas, alors non, cela ne fera pas ce que vous voulez. Ce dont vous avez vraiment besoin est un Multimap
faiblement évalué - quelque chose comme un MultimapMaker.weakValues()
. Cependant, il est pas MultimapMaker
actuellement: voir guava-libraries issue #142 pour une demande d'ajouter ceci. Pardon!
Merci pour l'aide et la clarification. Maintenant, je peux mieux formuler ma question: mon souci est que quand je fais map.get (key) .add (foo) pour ajouter une instance foo à l'ensemble, cela ajoutera-t-il aussi une forte référence à l'instance de foo et empêchera il d'être GCed? C'est pourquoi je me demandais si je devais utiliser un HashSet faible. –
Avoir édité + développé la partie centrale de ma réponse pour clarifier ceci (voir le paragraphe commençant 'Note aussi') – Cowan
Merci pour la bonne réponse! Cela a dissipé tous mes doutes. –