RFR: 8331208: Memory stress test that checks OutOfMemoryError stack trace fails

Doug Simon dnsimon at openjdk.org
Fri Apr 26 16:53:08 UTC 2024


On Tue, 23 Apr 2024 21:11:53 GMT, Doug Simon <dnsimon at openjdk.org> wrote:

> This pull request mitigates failures in memory stress tests that check the stack trace of an `OutOfMemoryError` for certain expected entries.
> 
> The stack trace of an OOME will [not be allocated once all preallocated OOMEs are used up](https://github.com/openjdk/jdk/blob/3d5eeac3a38ece4a23ea6da2dfe5939d64e81cea/src/hotspot/share/memory/universe.cpp#L722). If the only heap allocations performed in stressful conditions are those of the stress test, then the [4 preallocated OOMEs](https://github.com/openjdk/jdk/blob/f1d0e715b67e2ca47b525069d8153abbb33f75b9/src/hotspot/share/runtime/globals.hpp#L800) would be sufficient. However, it's possible for VM internal allocations to also occur during stressful conditions, especially in `-Xcomp` mode. For example, [CompileBroker::compile_method](https://github.com/openjdk/jdk/blob/3d5eeac3a38ece4a23ea6da2dfe5939d64e81cea/src/hotspot/share/compiler/compileBroker.cpp#L1399) will try to resolve the string constants in the constant pool of the method about to be compiled. This can fail as shown here:
> 
> V  [jvm.dll+0x62c23a]  Exceptions::_throw+0x11a  (exceptions.cpp:168)
> V  [jvm.dll+0x62d85b]  Exceptions::_throw_oop+0xab  (exceptions.cpp:140)
> V  [jvm.dll+0xbbce78]  MemAllocator::Allocation::check_out_of_memory+0x208  (memAllocator.cpp:138)
> V  [jvm.dll+0xbbcac8]  MemAllocator::allocate+0x158  (memAllocator.cpp:377)
> V  [jvm.dll+0x79bd05]  InstanceKlass::allocate_instance+0x95  (instanceKlass.cpp:1509)
> V  [jvm.dll+0x7ddeed]  java_lang_String::basic_create+0x9d  (javaClasses.cpp:273)
> V  [jvm.dll+0x7e43c0]  java_lang_String::create_from_unicode+0x60  (javaClasses.cpp:291)
> V  [jvm.dll+0xdb91a5]  StringTable::do_intern+0xb5  (stringTable.cpp:379)
> V  [jvm.dll+0xdba9f2]  StringTable::intern+0x1b2  (stringTable.cpp:368)
> V  [jvm.dll+0xdbaaa6]  StringTable::intern+0x86  (stringTable.cpp:328)
> V  [jvm.dll+0x51c8b1]  ConstantPool::string_at_impl+0x1d1  (constantPool.cpp:1251)
> V  [jvm.dll+0x51b95b]  ConstantPool::resolve_string_constants_impl+0xeb  (constantPool.cpp:800)
> V  [jvm.dll+0x4f2f8d]  CompileBroker::compile_method+0x31d  (compileBroker.cpp:1395)
> V  [jvm.dll+0x4f3474]  CompileBroker::compile_method+0xc4  (compileBroker.cpp:1348)
> 
> These internal allocations can occur before the allocations of the test and thus use up the pre-allocated OOMEs. As a result, the OOMEs triggered by the stress test may end up throwing the [default, shared OOME instance](https://github.com/openjdk/jdk/blob/3d5eeac3a38ece4a23ea6da2dfe5939d64e81cea/src/hotspot/...

src/hotspot/share/gc/shared/memAllocator.hpp line 133:

> 131:   SandboxedOOMEMark(JavaThread* thread, bool disable_events=false) {
> 132:     if (thread != nullptr) {
> 133:       _outer = thread->sandboxed_oome_mark();

Need for supporting recursion is shown by this stack trace:

V  [libjvm.dylib+0x4c9fe4]  CompileBroker::compile_method(methodHandle const&, int, int, methodHandle const&, int, CompileTask::CompileReason, DirectiveSet*, JavaThread*)+0x6b0
V  [libjvm.dylib+0x4c98d0]  CompileBroker::compile_method(methodHandle const&, int, int, methodHandle const&, int, CompileTask::CompileReason, JavaThread*)+0xcc
V  [libjvm.dylib+0x4a7434]  CompilationPolicy::event(methodHandle const&, methodHandle const&, int, int, CompLevel, nmethod*, JavaThread*)+0x2e0
V  [libjvm.dylib+0x355c14]  Runtime1::counter_overflow(JavaThread*, int, Method*)+0x268
v  ~RuntimeStub::counter_overflow Runtime1 stub 0x0000000116276c3c
J 4004 c1 jdk.internal.loader.URLClassPath.getLoader(I)Ljdk/internal/loader/URLClassPath$Loader; java.base at 23-internal (194 bytes) @ 0x000000010f55a7bc [0x000000010f558cc0+0x0000000000001afc]
J 3651 jvmci jdk.internal.loader.URLClassPath.getResource(Ljava/lang/String;Z)Ljdk/internal/loader/Resource; java.base at 23-internal (74 bytes) @ 0x0000000116ba628c [0x0000000116ba6200+0x000000000000008c]
J 3649 jvmci jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(Ljava/lang/String;)Ljava/lang/Class; java.base at 23-internal (64 bytes) @ 0x0000000116ba4ffc [0x0000000116ba4c40+0x00000000000003bc]
J 3640 jvmci jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(Ljava/lang/String;Z)Ljava/lang/Class; java.base at 23-internal (143 bytes) @ 0x0000000116ba26c0 [0x0000000116ba2440+0x0000000000000280]
J 3638 jvmci jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class; java.base at 23-internal (40 bytes) @ 0x0000000116ba17c0 [0x0000000116ba1680+0x0000000000000140]
J 3636 jvmci java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class; java.base at 23-internal (7 bytes) @ 0x0000000116ba137c [0x0000000116ba1300+0x000000000000007c]
v  ~StubRoutines::call_stub 0x00000001160f0190
V  [libjvm.dylib+0x856918]  JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x420
V  [libjvm.dylib+0x855618]  JavaCalls::call_virtual(JavaValue*, Klass*, Symbol*, Symbol*, JavaCallArguments*, JavaThread*)+0x218
V  [libjvm.dylib+0x8558b0]  JavaCalls::call_virtual(JavaValue*, Handle, Klass*, Symbol*, Symbol*, Handle, JavaThread*)+0x70
V  [libjvm.dylib+0x1024ca8]  SystemDictionary::load_instance_class_impl(Symbol*, Handle, JavaThread*)+0x114
V  [libjvm.dylib+0x10226c8]  SystemDictionary::load_instance_class(Symbol*, Handle, JavaThread*)+0x28
V  [libjvm.dylib+0x1021a7c]  SystemDictionary::resolve_instance_class_or_null(Symbol*, Handle, Handle, JavaThread*)+0x69c
V  [libjvm.dylib+0xf5ea64]  SignatureStream::as_klass(Handle, Handle, SignatureStream::FailureMode, JavaThread*)+0x60
V  [libjvm.dylib+0xd57894]  Method::load_signature_classes(methodHandle const&, JavaThread*)+0xf0
V  [libjvm.dylib+0x4c9c8c]  CompileBroker::compile_method(methodHandle const&, int, int, methodHandle const&, int, CompileTask::CompileReason, DirectiveSet*, JavaThread*)+0x358
V  [libjvm.dylib+0x4c98d0]  CompileBroker::compile_method(methodHandle const&, int, int, methodHandle const&, int, CompileTask::CompileReason, JavaThread*)+0xcc
V  [libjvm.dylib+0x4a7434]  CompilationPolicy::event(methodHandle const&, methodHandle const&, int, int, CompLevel, nmethod*, JavaThread*)+0x2e0
V  [libjvm.dylib+0x355c14]  Runtime1::counter_overflow(JavaThread*, int, Method*)+0x268
v  ~RuntimeStub::counter_overflow Runtime1 stub 0x0000000116276c3c
J 4003 c1 CountUppercase.identity(ILCountUppercase$Unloaded;)I (2 bytes) @ 0x000000010f558874 [0x000000010f5587c0+0x00000000000000b4]
j  CountUppercase.main([Ljava/lang/String;)V+61
v  ~StubRoutines::call_stub 0x00000001160f0190
V  [libjvm.dylib+0x856918]  JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x420
V  [libjvm.dylib+0x940bf8]  jni_invoke_static(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, JavaThread*)+0x14c
V  [libjvm.dylib+0x9475c0]  jni_CallStaticVoidMethod+0x16c
C  [libjli.dylib+0xa260]  invokeStaticMainWithArgs+0x84
C  [libjli.dylib+0xaa9c]  JavaMain+0x588
C  [libjli.dylib+0xd4a0]  ThreadJavaMain+0xc


Note the recursive call to `CompileBroker::compile_method` (which uses a `SandboxedOOMEMark`).

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/18925#discussion_r1579726535


More information about the hotspot-gc-dev mailing list