开发者

When does a Class object get garbage collected?

I was wondering if somebody could tell me when a Java Class object gets garbage collected. My use case is a cache (Map<Class<?>, Class<?>[]>) which holds the class-hierarchy of objects.

For instance:

The (short) hierarchy of String.class would be (descending): String开发者_如何学Python.class -> Object.class. A valid cache-entry for this type would be [KEY: String.class, VALUE: {String.class, Object.class}].

I guess String.class is a bad example since the String.class should be garbage-collected....

I need this cache for a serialization project I'm working on. When writing an object my system needs the hierarchy of this object for choosing the correct "Codecs (Serializers)". Collecting the hierarchy for each object would cause some overhead which is not necessary. But then I though about memory-leaks. Probably class-objects can be garbage-collected (Which i don't know) which would not work when using strong-references in my cache.

Do you think a WeakHashMap would be enough? Or do I have to use something like:

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

What do you think about this issue?


Without getting into the details of Class garbage collection in Java, I don't think you need to worry at all: The Class Objects themselves don't need to be collected to prevent a memory leak to accomplish what you want. After all, there will only ever be a single Class instance for java.lang.String. So if you put a reference to String.class into a Map (or any other data structure) you aren't creating a new instance of the String class, just a reference to the existing one.

As soon as your Map goes out of scope, the entire Map will be eligible for garbage collection.


Classes are garbage collected at the same time as their class loader. So non-strong references are important if you want your code to work in the presence of transient class loaders.

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

This almost works. You can't have an array of a generic type. I suggest using a List instead.

This is kind of interning rather the caching. It shouldn't really matter in this case as the amount of memory used per key is tiny in comparison to the class. If you really wanted a cache you would need to use ReferenceQueue for eviction and something like:

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

(If you want, the angles could be cleaned up by introducing classes [with behaviour] that can be used for the key and value.)


You can't tell the exact time an object is garbage collected, not even when calling the garbage collector (Runtime.getRuntime().gc();).

Furthermore, using WeakHashMap for caching is usually a bad choice since weak references are used only for the keys and not for the values. Just google, you'll find a lot of helpful articles, e.g.

  • http://www.codeinstructions.com/2008/09/weakhashmap-is-not-cache-understanding.html
  • several issues at http://www.javaspecialists.eu/
  • http://www.java2s.com/Tutorial/Java/0140_Collections/0340_WeakHashMap.htm

Finally, you should check whether you really need caching (e.g. with a profiler like JVisualVM) since you are using String and Class objects...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜