Question

By "released" I mean there are no references to the classloader remaining.

We're running into a problem where a frequently-redeployed Java EE application eats up permgen space. Analysis shows that a singleton in the Java EE app has passed references to application-classloader objects outside of the application (in violation of Java EE rules) and isn't clearing them when the app is undeployed.

Assuming there are no other references remaining to the singleton or the class object, will the singleton's finalize() be called when its class's classloader is released? I'd like to clear the rogue in-bound references there. Or am I in a catch-22 where finalize won't get called until the classloader itself can be garbage-collected - and thus will never be called because of the rogue external references?

The main question here is perhaps:

Will a class object be garbage-collected in this case where its classloader can't be yet? This may be dependent on the specification of classloader behavior, or may be implementation-dependent.

References (the other kind! ;-)) would be appreciated, but aren't necessary.

Was it helpful?

Solution

A class with a static reference to it, will is eligible for garbage collection only, if the class loader is eligible for GCing and there are no other references to it.

A class or interface may be unloaded if and only if its defining class loader may be reclaimed by the garbage collector.

http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.7

Furthermore every class has a reference to its classloader. So a class loader is not eligible for GCing as long as there are references to classes loaded by it or objects of those classes from a non collectible objects.

The finalizer is run some time after an object becomes eligible for garbage collection and before the actual GC takes place.

The approach to free incoming references, that prevent GCing, in a finalizer does not work. The finalizer will not be called as long as such references exist because they prevent the object from becoming eligible for garbage collection. For example you cannot break this reference chain from the inside:

singleton instance <--- singleton class <--- class loader <--
<-- any class loaded by that class loader  <-- any object of such a class
<-- object loaded by another classloader referencing such an object or class

OTHER TIPS

The behaviour of finalisers is not changed the class loader or the use of perm gen, although it does make the performance issue worse. Objects cannot be collected until after the finaliser is run. So (simplifying by assuming non-concurrent, and ignoring weak/soft/phantom) there is a run of the GC that determines that there are no active references to the object graph including the class loader. The finalisers are added to the finaliser queue and then executed. Then after some subsequent pass of the GC the memory can be recovered. This requires a full GC including over the perm gen space, which is generally infrequent and can be disabled.

Anyway, don't use (stateful) singletons.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top