简体   繁体   中英

Does a static final Object ever get deleted by Garbage Collector?

I have previously used Custom Objects in a Service in Java that always keeps running at the back end and I have sometimes got Bug reports with traces that showed NULL_POINTER_EXCEPTION as the object was destroyed by the Garbage Collector. As I have all high end devices I am unable to test this that does a static final object get destroyed by the garbage collector or not?

In normal Java App (I'm not sure about Android), a static final referenced Object is GCed only when its proper ClassLoader is unloaded.

For example when having multiple web-apps in a container (such as Tomcat), undeploying each web-app, unloades application's ClassLoader, so application's static final referenced Object will be GCed. But objects loaded by other ClassLoaders (such as other web-app's ClassLoaders, common ClassLoader, boot-strap ClassLoader) won't be GCed.

So the answer to your question is: it depends on whether the ClassLoader is de-activated or not.

Does a static final Object ever get deleted by Garbage Collector?

I can think of three circumstances where this could happen:

  1. The classloader that loaded the class with the static becomes unreachable. But this can only happen after your code has reached a point where nothing could possibly notice that the object is GC'd!

  2. Something has used "nasty reflective tricks" to assign null to the static final . (Yes, it can be done ...)

  3. Something is subtly corrupting the heap; eg some buggy JNI / JNA code.

Note that since you are (apparently) observing the effect of the object being GC'd, it CANNOT be a direct result of the classloader being GC'd. Something else must have happened to make it possible for the classloader and the final static to be GC'ed ... if that is what is actually happening here.


Actually, I suspect that your problem is not GC-related. Rather, I suspect that your service is dying due to an unchecked exception that is not being logged. The default behaviour for uncaught exceptions on threads other than "main" is to silently ignore them.

I suggest that you check that your service threads are logging all exceptions, either with a catch in the run() method, or in an "uncaught exception handler".

The JVM uses a mark-sweep GC algorithm, which has to examine all the live refereces in the GC "root" locations (like all the objects in the current call stack). Each live object is "marked" as being alive, and any object referred to by a live object is also marked as being alive.

After the completion of the mark phase, the GC sweeps through the heap, freeing memory for all unmarked objects (and compacting the memory for the remaining live objects).

I'm going to say "no, the 'final' modifer doesn't help the GC reduce its workload".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM