Class对象什么时候收集垃圾?

时间:2011-09-04 10:36:55

标签: java class caching garbage-collection weak

我想知道是否有人可以告诉我Java Class对象何时被垃圾收集。我的用例是一个缓存(Map<Class<?>, Class<?>[]>),它保存了对象的类层次结构。

例如:

String.class的(简短)层次结构将是(降序):String.class - &gt; Object.class。此类型的有效缓存条目为[KEY: String.class, VALUE: {String.class, Object.class}]

我猜String.class是一个不好的例子,因为String.class应该被垃圾收集....

我需要这个缓存来处理我正在进行的序列化项目。在编写对象时,我的系统需要此对象的层次结构来选择正确的“编解码器(序列化器)”。收集每个对象的层次结构会导致一些不必要的开销。但后来我关于内存泄漏。可能垃圾收集(我不知道)类对象可能在我的缓存中使用强引用时无效。

你认为WeakHashMap就够了吗?或者我必须使用类似的东西:

Map<WeakReference<Class<?>>, WeakReference<Class<?>>[]> ?

您如何看待这个问题?

3 个答案:

答案 0 :(得分:2)

没有深入了解Java中的类垃圾收集的细节,我认为你根本不需要担心:不需要收集类对象本身来防止内存泄漏来实现你想要的。毕竟,java.lang.String只有一个Class实例。因此,如果将String.class的引用放入Map(或任何其他数据结构),则不是要创建String类的新实例,而只是对现有实例的引用。

只要Map超出范围,整个Map就有资格进行垃圾回收。

答案 1 :(得分:0)

你无法告诉对象被垃圾收集的确切时间,甚至在调用垃圾收集器时也是如此(Runtime.getRuntime()。gc();)。

此外,使用WeakHashMap进行缓存通常是一个糟糕的选择,因为弱引用仅用于键而不用于值。只是谷歌,你会发现很多有用的文章,例如

最后,您应该检查是否确实需要缓存(例如,使用像JVisualVM这样的分析器),因为您正在使用String和Class对象......

答案 2 :(得分:0)

类与类加载器同时进行垃圾回收。因此,如果您希望代码在瞬态类加载器的存在下工作,那么非强引用非常重要。

Map<WeakReference<Class<?>>, WeakReference<Class<?>>[]>

这几乎可行。您不能拥有泛型类型的数组。我建议改为使用List

这是一种实习而非缓存。在这种情况下,它应该不重要,因为每个键使用的内存量与类相比很小。如果您真的想要一个缓存,则需要使用ReferenceQueue进行驱逐,例如:

Map<SoftReference<WeakReference<Class<?>>>, List<WeakReference<Class<?>>>>

(如果您愿意,可以通过引入可用于键和值的类[带有行为]来清除角度。)