3

我需要定义一个弱引用Map,它的值是一个Set。我使用 Google 收藏的 MapMaker,如下所示:

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

那么,对于Set<Foo>,我可以使用普通的HashSet吗?或者,我是否必须创建一个弱 HashSet,如下所示:

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

为什么?

另一个问题,我的地图的关键是Class对象,Class对象什么时候变得弱可达?换句话说,Class 对象的生命周期是多少?

谢谢。

更新:第一个问题不是很清楚。我担心的是,当我map.get(key).add(foo)将 foo 实例添加到 Set 时,这是否也会添加对 foo 实例的强引用,从而防止它被 GCed?这就是为什么我想知道是否应该使用弱 HashSet。

4

1 回答 1

4

首先回答第二部分,只有当负责的对象依次被垃圾收集时,Class对象才有资格进行垃圾收集。Classloader请参阅JLS 的第 12.7 节

当且仅当其定义的类加载器可以被垃圾收集器回收时,类或接口才能被卸载,如第 12.6 节中所讨论的。引导加载程序加载的类和接口可能不会被卸载。

所以 a可能WeakReference<Class>不太可能做你希望的事情(尽管我不是 100% 清楚你寻找什么)。

现在,回到第一部分——你需要一个弱 HashSet 吗?这又取决于你想要做什么。如果您希望在不再引用本身Map时回收条目,不,您不需要 weak 。(顺便说一下,google-collections 对弱引用值和键使用相等引用,因此这里没有棘手的相等问题)。在最后一次对 的引用之后的下一次 GC被丢弃,该条目将被回收。SetHashMapSetMap

另请注意,这也将允许Foos 被垃圾收集;一旦你放弃对 的引用Set<Foo>Foos 只能很弱地到达并且可以被丢弃。请参阅java.lang.ref 包的 Javadoc

如果某个对象可以被某个线程访问而无需遍历任何引用对象,则该对象是强可达的。[...] 一个对象是弱可达的,如果它既不是强可达也不是软可达,但可以通过遍历弱引用来达到。当对弱可达对象的弱引用被清除时,该对象就有资格进行终结。

因此,如果唯一的引用链是(对 的强引用Map)→(Map对 的弱引用Set)→(对 的Set强引用Foo),则Foo可以对 进行垃圾收集。

但是,我有一个挥之不去的怀疑,这不是你所追求的。我怀疑您想要的是在Foo不再引用最后一个条目时回收 Map 条目;你不是持有对Set<Foo>自身的引用,而是对单个Foo对象的引用。

如果是这种情况,那么不,这不会做你想要的。你真正需要的是一个弱值Multimap——比如MultimapMaker.weakValues(). 但是,目前没有MultimapMaker请参阅guava-libraries issue #142以获取添加此内容的请求。对不起!

于 2010-05-08T10:31:12.637 回答