4

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

例如:

的(短)层次结构String.class将是(降序):String.class-> Object.class。这种类型的有效缓存条目是[KEY: String.class, VALUE: {String.class, Object.class}].

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

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

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

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

你怎么看这个问题?

4

3 回答 3

2

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

一旦您Map超出范围,整个Map将有资格进行垃圾收集。

于 2011-09-04T10:43:18.467 回答
0

类在其类加载器的同时被垃圾收集。因此,如果您希望代码在存在瞬态类加载器的情况下工作,那么非强引用很重要。

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

这几乎可以工作。你不能有一个泛型类型的数组。我建议使用 aList代替。

这是一种实习,而不是缓存。在这种情况下,这并不重要,因为与类相比,每个键使用的内存量很小。如果你真的想要一个缓存,你需要使用ReferenceQueue驱逐和类似的东西:

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

(如果您愿意,可以通过引入可用于键和值的类 [with behavior] 来清理角度。)

于 2011-09-04T12:56:41.523 回答
0

您无法确定对象被垃圾收集的确切时间,即使在调用垃圾收集器 (Runtime.getRuntime().gc();) 时也是如此。

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

最后,您应该检查您是否真的需要缓存(例如使用 JVisualVM 之类的分析器),因为您使用的是 String 和 Class 对象...

于 2011-09-04T10:54:08.290 回答