RFR: 8156500: deadlock provoked by new stress test com/sun/jdi/OomDebugTest.java

David Holmes david.holmes at oracle.com
Wed Jun 29 05:19:23 UTC 2016


Hi Mandy,

On 29/06/2016 12:28 PM, Mandy Chung wrote:
>
>> On Jun 28, 2016, at 4:23 PM, David Holmes <david.holmes at oracle.com> wrote:
>>
>> On 29/06/2016 8:43 AM, Kim Barrett wrote:
>>> Updated webrevs:
>>>
>>> Full:
>>> http://cr.openjdk.java.net/~kbarrett/8156500/jdk.01/
>>> http://cr.openjdk.java.net/~kbarrett/8156500/hotspot.01/
>>>
>>> Incremental:
>>> http://cr.openjdk.java.net/~kbarrett/8156500/jdk.01.inc/
>>
>> Did Reference<?> not work? Just curious. I used to be a qualified Java programmer back in the Java 5 era, but wildcards were always a bit iffy :)
>
>
> A related post in compiler-dev w.r.t. Reference<? super Object>:
>   http://mail.openjdk.java.net/pipermail/compiler-dev/2014-January/008457.html
>
> Looks like no reply on that thread though.
>
>>
>>> http://cr.openjdk.java.net/~kbarrett/8156500/hotspot.01.inc/
>>>
>>> Still investigating the initialization order for core exceptions.
>>
>> I suspect it is as Coleen indicated that the module changes introduced the new failure path that you hit. I did a quick check of the initialization order in an old b50:
>>
>> 33 Initializing 'java/lang/Throwable' (0x0000001780002990)
>> ...
>> 46 Initializing 'java/lang/Exception'(no method) (0x0000001780003158)
>> 47 Initializing 'java/lang/InterruptedException'(no method) (0x00000017800178a8)
>>
>> Compare that with a current build:
>>
>> 60 Initializing 'java/lang/ref/Reference$ReferenceHandler' (0x000000080001e3f0)
>> 61 Initializing 'java/lang/Throwable' (0x00000008000029f8)
>> 62 Initializing 'java/lang/Exception'(no method) (0x00000008000031a8)
>> 63 Initializing 'java/lang/InterruptedException'(no method) (0x000000080001e6e0)
>> 64 Initializing 'java/lang/ref/PhantomReference'(no method) (0x0000000800006440)
>>
>
> How do you get this list?

For current builds: java -Xlog:class+init -version (and I trimmed the 
output)

For slightly older builds: java -Xlog:classinit -version

For pre UL you need a fastdebug build and: java 
-XX:+TraceClassInitialization -version

>
>> Initialization of Throwable is much, much later (large parts of java.lang and java.util are now initialized first!) and is obviously a direct consequence of preinitializing InterruptedException.
>>
>
> Do you mind trying b110 before JEP 261 was integrated in jdk-9+111 and see any difference?

Here's fragment from b109:

31 Initializing 'java/lang/ref/Reference' (0x0000000800005a08)
32 Initializing 'java/lang/ref/Reference$Lock'(no method) 
(0x00000008000181c0)
33 Initializing 'java/lang/ref/Reference$ReferenceHandler' 
(0x00000008000183b8)
34 Initializing 'java/lang/Throwable' (0x00000008000028f0)

> initPhase1 is expected to be called very early in the VM initialization after the primordial classes are loaded.
>
> IIRC, the exception classes are preallocated to improve diagnosability in the case when we run out of memory VM can still throw a preallocated instance with an preallocated stack trace buffer.  I don’t think these exception classes are expected to be loaded initPhase1.

So here is what I see has happened.

Looking back at 9-b01, before we forced the initialization of 
InterruptedException and thus Throwable we find:

58 Initializing 'java/lang/Throwable' (0x0000000800002990)

So Kim is right this was working by accident. It just seems that back 
then there was less memory required by the initialization of all the 
collection and other classes and so we didn't run into this problem.

Post the InterruptedException change the initialization order made it 
unlikely an OOME could be encountered before Throwable was initialized 
(and after we have reached a point where we can throw without the VM 
crashing or instead doing a vm_exit_during_initialization).

Post modules those collection classes, and others, are now done earlier 
again and before Throwable. And presumably their memory demands have 
increased.

Although we preallocate the OutOfMemoryError instances, and avoid 
executing any java code to do so, we can't necessarily** "throw" them 
until after Throwable is initialized. We now have a lot more 
initialization occurring before we init Throwable and so OOME is more 
likely and so it will fail as Kim observed.

** I say necessarily because I still believe it is the fact we attempt 
to fill in the stacktrace that leads to the dependency on Throwable 
being initialized, and we should be able to avoid that if we check the 
VM initialization state in gen_out_of_memory_error().

Thanks,
David

> More to dig here.
>
> Mandy
>
>> So I would say that the module change did break this and that initialization of Throwable (only) should be restored to a much higher place in the initialization sequence.
>>
>> Thanks,
>> David
>>
>


More information about the hotspot-dev mailing list