2010-05-08 6 views
3

J'ai besoin de définir une carte de référence faible, dont la valeur est un ensemble. J'utilise cartographe comme des collections Google ceci:Utilisation correcte de Java Weak Reference dans le cas de collections imbriquées

Map<Class<? extends Object>, Set<Foo>> map = new MapMaker().weakKeys().weakValues().makeMap(); 

Ainsi, pour Set<Foo>, puis-je utiliser un HashSet normal? Ou, dois-je créer un HashSet faible, comme ceci:

Collections.newSetFromMap(new WeakHashMap<Foo, Boolean>()); 

Et pourquoi?

Une autre question, la clé de ma carte est des objets de classe, quand un objet de classe deviendra-t-il faiblement accessible? En d'autres termes, quelle est la durée de vie d'un objet Class?

Merci.

Mise à jour: La 1ère question n'est pas vraiment claire. Mon souci était que quand je fais map.get(key).add(foo) pour ajouter l'instance de foo à l'ensemble, ceci ajoutera-t-il également une référence forte à l'instance de foo et l'empêchera ainsi d'être GCed? C'est pourquoi je me demandais si je devais utiliser un HashSet faible.

Répondre

4

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!

+0

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. –

+0

Avoir édité + développé la partie centrale de ma réponse pour clarifier ceci (voir le paragraphe commençant 'Note aussi') – Cowan

+0

Merci pour la bonne réponse! Cela a dissipé tous mes doutes. –

Questions connexes