JDK-8218700 : infinite loop in HotSpotJVMCIMetaAccessContext.fromClass after OutOfMemoryError
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 13
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2019-02-09
  • Updated: 2019-08-15
  • Resolved: 2019-05-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 13
13 b20Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
----------System.out:(37/1901)----------
Stress time: 30 seconds
Stress iterations factor: 1
Stress threads factor: 1
Stress runs factor: 1
Max memory: 687865856
Sleep time: 500
Iterations: 0
Number of threads: 20
Seed: 1549432315472
Run GC thread: false
Run mem diag thread: false
Run forever: false
Starting Thread[gc.lock.LockerTest$Worker@406e1e16,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@6699871,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@3647a804,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@3f7f7a05,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@19372dec,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@53d794ab,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@585b115d,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@1cb0f701,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@3c48f136,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@53d548d8,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@53047a06,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@48179798,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@33ad0eed,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@4a4703c8,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@3a6384cc,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@4ebc7f4f,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@15bdca13,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@6716c22f,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@41756fe5,5,MainThreadGroup]
Starting Thread[gc.lock.LockerTest$Worker@6c9e2683,5,MainThreadGroup]
Uncaught exception while adjusting compilation level: java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
	<<no stack trace available>>
No unexpected exceptions/errors are thrown
Timeout refired 1200 times
----------System.err:(4/255)----------
Exception in thread "HotSpotGraalManagement Bean Registration" 
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "HotSpotGraalManagement Bean Registration"
java.lang.OutOfMemoryError: Java heap space
STATUS:Passed.
Comments
The problem is triggered by JDK-8222941.
24-04-2019

Thanks [~dtitov]! I'm able to reproduce it now. How were you able to print out the ClassValue cache?
23-04-2019

[~dtitov] Daniil, I don't see this test failing recently. Do you have any tips on how to reproduce the failure?
18-04-2019

This looks like it needs to get passed back to compiler folk to determine what should be happening with that Java JVMCI code. Other than the test being executed I see nothing that connects this to JVM TI. But thank you for the detailed analysis [~dtitov]!
08-04-2019

It turned out that JVMCI CompilerThread0 runs in the endless loop (lines 162-173, src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java). The javaClass passed in the method is java.lang.String. javaType returned on line 164 from type.get() is null. 160 public ResolvedJavaType fromClass(Class<?> javaClass) { 161 ResolvedJavaType javaType = null; 162 while (javaType == null) { 163 WeakReference<ResolvedJavaType> type = resolvedJavaType.get(javaClass); 164 javaType = type.get(); 165 if (javaType == null) { 166 /* 167 * If the referent has become null, clear out the current value and let computeValue 168 * above create a new value. Reload the value in a loop because in theory the 169 * WeakReference referent can be reclaimed at any point. 170 */ 171 resolvedJavaType.remove(javaClass); 172 } 173 } 174 return javaType; 175 } resolvedJavaType.get(javaClass) on line 163 reads the element from javaClass.classValueMap.getCache(), in this case the cache contains 2 elements and resolvedJavaType.hashCodeForCache is 0 so the method returns the first element. resolvedJavaType.remove(javaClass) on line 173 removes entry from javaClass.classValueMap that is already empty, so it does not affect anything. cache = {ClassValue$Entry[32]@1260} 0 = {ClassValue$Entry@1261} value = {WeakReference@1218} referent = {ClassValue$Version@1268} queue = {ReferenceQueue$Null@1269} next = null discovered = null 1 = {ClassValue$Entry@1261} value = {WeakReference@1218} referent = {ClassValue$Version@1268} queue = {ReferenceQueue$Null@1269} next = null discovered = null
06-04-2019

VMThread just keeps running in the loop (lines 494-532, hotspot/share/runtime/vmThread.cpp) and _cur_vm_operation is always NULL, timedout is true. 494 while (!should_terminate() && _cur_vm_operation == NULL) { 495 // wait with a timeout to guarantee safepoints at regular intervals 496 bool timedout = 497 VMOperationQueue_lock->wait(Mutex::_no_safepoint_check_flag, 498 GuaranteedSafepointInterval); 499 500 // Support for self destruction 501 if ((SelfDestructTimer != 0) && !VMError::is_error_reported() && 502 (os::elapsedTime() > (double)SelfDestructTimer * 60.0)) { 503 tty->print_cr("VM self-destructed"); 504 exit(-1); 505 } 506 507 if (timedout) { 508 // Have to unlock VMOperationQueue_lock just in case no_op_safepoint() 509 // has to do a handshake. 510 MutexUnlockerEx mul(VMOperationQueue_lock, Mutex::_no_safepoint_check_flag); 511 if ((_cur_vm_operation = VMThread::no_op_safepoint()) != NULL) { 512 // Force a safepoint since we have not had one for at least 513 // 'GuaranteedSafepointInterval' milliseconds and we need to clean 514 // something. This will run all the clean-up processing that needs 515 // to be done at a safepoint. 516 SafepointSynchronize::begin(); 517 #ifdef ASSERT 518 if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot(); 519 #endif 520 SafepointSynchronize::end(); 521 _cur_vm_operation = NULL; 522 } 523 } 524 _cur_vm_operation = _vm_queue->remove_next(); 525 526 // If we are at a safepoint we will evaluate all the operations that 527 // follow that also require a safepoint 528 if (_cur_vm_operation != NULL && 529 _cur_vm_operation->evaluate_at_safepoint()) { 530 safepoint_ops = _vm_queue->drain_at_safepoint_priority(); 531 } 532 }
06-04-2019

jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.shutdown() is called from before_exit() method in java.cpp 441 #if INCLUDE_JVMCI 442 // We are not using CATCH here because we want the exit to continue normally. 443 Thread* THREAD = thread; 444 JVMCIRuntime::shutdown(THREAD); 445 if (HAS_PENDING_EXCEPTION) { 446 HandleMark hm(THREAD); 447 Handle exception(THREAD, PENDING_EXCEPTION); 448 CLEAR_PENDING_EXCEPTION; 449 java_lang_Throwable::java_printStackTrace(exception, THREAD); 450 } 451 #endif Here is the stack trace: #19 JVMCIRuntime::shutdown(Thread*) at src/hotspot/share/jvmci/jvmciRuntime.cpp:893 #20 before_exit(JavaThread*) at src/hotspot/share/runtime/java.cpp:444 #21 Threads::destroy_vm() at src/hotspot/share/runtime/thread.cpp:4345 #22 jni_DestroyJavaVM_inner(JavaVM_*) [inlined] at src/hotspot/share/prims/jni.cpp:4068 #23 ::jni_DestroyJavaVM(JavaVM *) at src/hotspot/share/prims/jni.cpp:4086 #24 JavaMain () #25 ThreadJavaMain at src/java.base/macosx/native/libjli/java_md_macosx.m:723 #26 _pthread_body ()
06-04-2019

Also how do we get to jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.shutdown in the DestroyJavaVM thread?
02-04-2019

The stacks show that a safepoint is active. What is the VMThread trying to do at the safepoint?
02-04-2019

The stack traces (see stracktrace.txt attached) shows that "DestroyJavaVM" thread is blocked waiting for jdk.vm.ci.hotspot.HotSpotJVMCIRuntime lock while "JVMCI CompilerThread0" thread is holding this lock and trying to initialize the compiler but for some reason doesn't do any progress. "DestroyJavaVM" #28 prio=5 os_prio=31 cpu=427.97ms elapsed=53.07s tid=0x00007fb6333b6800 nid=0x2203 waiting for monitor entry [0x000070000044e000] java.lang.Thread.State: BLOCKED (on object monitor) Thread: 0x00007fb6333b6800 [0x2203] State: _at_safepoint _at_poll_safepoint 0 JavaThread state: _thread_blocked at jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.getVmEventListeners(jdk.internal.vm.ci@13-internal/HotSpotJVMCIRuntime.java:266) - waiting to lock <0x0000000781bdde68> (a jdk.vm.ci.hotspot.HotSpotJVMCIRuntime) at jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.shutdown(jdk.internal.vm.ci@13-internal/HotSpotJVMCIRuntime.java:550) "JVMCI CompilerThread0" #5 daemon prio=9 os_prio=31 cpu=52597.48ms elapsed=83.86s tid=0x00007fb631888800 nid=0x5803 runnable [0x0000700000e6b000] java.lang.Thread.State: RUNNABLE Thread: 0x00007fb631888800 [0x5803] State: _at_safepoint _at_poll_safepoint 0 JavaThread state: _thread_blocked Compiling: 314 4 java.lang.ref.Reference::reachabilityFence (1 bytes) at java.lang.ClassValue$ClassValueMap.removeEntry(java.base@13-internal/ClassValue.java:489) - locked <0x0000000781b351a8> (a java.lang.ClassValue$ClassValueMap) at java.lang.ClassValue.remove(java.base@13-internal/ClassValue.java:172) at jdk.vm.ci.hotspot.HotSpotJVMCIMetaAccessContext.fromClass(jdk.internal.vm.ci@13-internal/HotSpotJVMCIMetaAccessContext.java:171) at jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.fromClass(jdk.internal.vm.ci@13-internal/HotSpotJVMCIRuntime.java:338) at jdk.vm.ci.hotspot.HotSpotMetaAccessProvider.lookupJavaType(jdk.internal.vm.ci@13-internal/HotSpotMetaAccessProvider.java:65) at org.graalvm.compiler.core.common.spi.JavaConstantFieldProvider.<init>(jdk.internal.vm.compiler@13-internal/JavaConstantFieldProvider.java:51) at org.graalvm.compiler.hotspot.meta.HotSpotConstantFieldProvider.<init>(jdk.internal.vm.compiler@13-internal/HotSpotConstantFieldProvider.java:44) at org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider.<init>(jdk.internal.vm.compiler@13-internal/HotSpotGraalConstantFieldProvider.java:52) at org.graalvm.compiler.hotspot.amd64.AMD64HotSpotBackendFactory.createBackend(jdk.internal.vm.compiler@13-internal/AMD64HotSpotBackendFactory.java:107) at org.graalvm.compiler.hotspot.HotSpotGraalRuntime.<init>(jdk.internal.vm.compiler@13-internal/HotSpotGraalRuntime.java:182) at org.graalvm.compiler.hotspot.HotSpotGraalCompilerFactory.createCompiler(jdk.internal.vm.compiler@13-internal/HotSpotGraalCompilerFactory.java:150) at org.graalvm.compiler.hotspot.HotSpotGraalCompilerFactory.createCompiler(jdk.internal.vm.compiler@13-internal/HotSpotGraalCompilerFactory.java:128) at org.graalvm.compiler.hotspot.HotSpotGraalCompilerFactory.createCompiler(jdk.internal.vm.compiler@13-internal/HotSpotGraalCompilerFactory.java:48) at jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.getCompiler(jdk.internal.vm.ci@13-internal/HotSpotJVMCIRuntime.java:425) - locked <0x0000000781bdde68> (a jdk.vm.ci.hotspot.HotSpotJVMCIRuntime) at jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.compileMethod(jdk.internal.vm.ci@13-internal/HotSpotJVMCIRuntime.java:524)
02-04-2019

The OutOfMemoryError's don't seem to directly cause the failure. Output shows STATUS:Passed. but also No unexpected exceptions/errors are thrown Timeout refired 1200 times Changing to hotspot/jvmti for evaluation.
12-02-2019