On 01/21/2014 08:57 AM, David Holmes wrote:
[Loaded java.util.TimeZone from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfo from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfoFile from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfoFile$1 from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded java.io.DataInput from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded java.io.DataInputStream from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
*[Loaded sun.misc.Cleaner from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]*

Curious. I wonder what the controlling factor is ??

The Cleaner is usually loaded by ReferenceHandler in JDK8 in the 1st execution of it's loop. It looks like JDK8 system initialization produces at least one XXXReference that is cleared before main() method is entered (debugging, I found it's a Finalizer for a FileInputStream - perhaps of the stream that loads the TimeZone data), so ReferenceHandler thread is woken-up, executes the instanceof Cleaner check and this loads the class. I put the following printfs in an original ReferenceHandler:

    System.out.println("Before using Cleaner...");
    // Fast path for cleaners
    if (r instanceof Cleaner) {
        ((Cleaner)r).clean();
        continue;
    }
    System.out.println("After using Cleaner...");


...and the empty main() test with -verbose:class prints:

...
[Loaded java.io.DataInput from /home/peter/work/hg/jdk8-tl/build/linux-x86_64-normal-server-release/images/j2sdk-image/jre/lib/rt.jar] [Loaded java.io.DataInputStream from /home/peter/work/hg/jdk8-tl/build/linux-x86_64-normal-server-release/images/j2sdk-image/jre/lib/rt.jar]
*Before using Cleaner...**
**[Loaded sun.misc.Cleaner from out/production/jdk]**
**After using Cleaner...*
[Loaded java.io.ByteArrayInputStream from /home/peter/work/hg/jdk8-tl/build/linux-x86_64-normal-server-release/images/j2sdk-image/jre/lib/rt.jar] [Loaded sun.util.calendar.ZoneInfoFile$ZoneOffsetTransitionRule from /home/peter/work/hg/jdk8-tl/build/linux-x86_64-normal-server-release/images/j2sdk-image/jre/lib/rt.jar]

...


But sometimes, It seems, the VM is not so quick in clearing the early XXXReferences and/or the ReferenceHandler start-up is delayed and the 1st iteration of the loop is executed after the OOMEInReferenceHandler test already fills the heap and consequently loading of Cleaner class throws OOME in instanceof check...

My proposed fix is very aggressive. It pre-loads classes, initializes them and watches for OOMEs thrown in all ocasions. It might be that pre-loading Cleaner class in ReferenceHandler initialization would be sufficient to fix this intermittent failure. Or do you think instanceof check could throw OOME for some other reason besides loading of the class?


Regards, Peter

Reply via email to