我想知道是否有人可以告诉我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<?>>[]> ?
您如何看待这个问题?
答案 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<?>>>>
(如果您愿意,可以通过引入可用于键和值的类[带有行为]来清除角度。)