Skip to content

Commit ad1dc9c

Browse files
y1yang0dongyun.tdy
and
dongyun.tdy
committedDec 23, 2021
8278125: Some preallocated OOMEs are missing stack trace
Co-authored-by: dongyun.tdy <dongyun.tdy@alibaba-inc.com> Reviewed-by: dholmes, coleenp
1 parent eaefb1a commit ad1dc9c

File tree

4 files changed

+87
-3
lines changed

4 files changed

+87
-3
lines changed
 

‎src/hotspot/share/memory/universe.cpp

+15-1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ OopHandle Universe::_delayed_stack_overflow_error_message;
110110
OopHandle Universe::_preallocated_out_of_memory_error_array;
111111
volatile jint Universe::_preallocated_out_of_memory_error_avail_count = 0;
112112

113+
// Message details for OOME objects, preallocate these objects since they could be
114+
// used when throwing OOME, we should try to avoid further allocation in such case
115+
OopHandle Universe::_msg_metaspace;
116+
OopHandle Universe::_msg_class_metaspace;
117+
113118
OopHandle Universe::_null_ptr_exception_instance;
114119
OopHandle Universe::_arithmetic_exception_instance;
115120
OopHandle Universe::_virtual_machine_error_instance;
@@ -540,7 +545,6 @@ static void reinitialize_itables() {
540545
ClassLoaderDataGraph::classes_do(&cl);
541546
}
542547

543-
544548
bool Universe::on_page_boundary(void* addr) {
545549
return is_aligned(addr, os::vm_page_size());
546550
}
@@ -640,6 +644,14 @@ oop Universe::gen_out_of_memory_error(oop default_err) {
640644
}
641645
}
642646

647+
bool Universe::is_out_of_memory_error_metaspace(oop ex_obj) {
648+
return java_lang_Throwable::message(ex_obj) == _msg_metaspace.resolve();
649+
}
650+
651+
bool Universe::is_out_of_memory_error_class_metaspace(oop ex_obj) {
652+
return java_lang_Throwable::message(ex_obj) == _msg_class_metaspace.resolve();
653+
}
654+
643655
// Setup preallocated OutOfMemoryError errors
644656
void Universe::create_preallocated_out_of_memory_errors(TRAPS) {
645657
InstanceKlass* ik = vmClasses::OutOfMemoryError_klass();
@@ -659,9 +671,11 @@ void Universe::create_preallocated_out_of_memory_errors(TRAPS) {
659671
java_lang_Throwable::set_message(oom_array->obj_at(_oom_c_heap), msg());
660672

661673
msg = java_lang_String::create_from_str("Metaspace", CHECK);
674+
_msg_metaspace = OopHandle(vm_global(), msg());
662675
java_lang_Throwable::set_message(oom_array->obj_at(_oom_metaspace), msg());
663676

664677
msg = java_lang_String::create_from_str("Compressed class space", CHECK);
678+
_msg_class_metaspace = OopHandle(vm_global(), msg());
665679
java_lang_Throwable::set_message(oom_array->obj_at(_oom_class_metaspace), msg());
666680

667681
msg = java_lang_String::create_from_str("Requested array size exceeds VM limit", CHECK);

‎src/hotspot/share/memory/universe.hpp

+8
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ class Universe: AllStatic {
132132
// number of preallocated error objects available for use
133133
static volatile jint _preallocated_out_of_memory_error_avail_count;
134134

135+
// preallocated message detail strings for error objects
136+
static OopHandle _msg_metaspace;
137+
static OopHandle _msg_class_metaspace;
138+
135139
static OopHandle _null_ptr_exception_instance; // preallocated exception object
136140
static OopHandle _arithmetic_exception_instance; // preallocated exception object
137141
static OopHandle _virtual_machine_error_instance; // preallocated exception object
@@ -294,6 +298,10 @@ class Universe: AllStatic {
294298
static oop out_of_memory_error_retry();
295299
static oop delayed_stack_overflow_error_message();
296300

301+
// If it's a certain type of OOME object
302+
static bool is_out_of_memory_error_metaspace(oop ex_obj);
303+
static bool is_out_of_memory_error_class_metaspace(oop ex_obj);
304+
297305
// The particular choice of collected heap.
298306
static CollectedHeap* heap() { return _collectedHeap; }
299307

‎src/hotspot/share/utilities/exceptions.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,9 @@ volatile int Exceptions::_out_of_memory_error_metaspace_errors = 0;
461461
volatile int Exceptions::_out_of_memory_error_class_metaspace_errors = 0;
462462

463463
void Exceptions::count_out_of_memory_exceptions(Handle exception) {
464-
if (exception() == Universe::out_of_memory_error_metaspace()) {
464+
if (Universe::is_out_of_memory_error_metaspace(exception())) {
465465
Atomic::inc(&_out_of_memory_error_metaspace_errors, memory_order_relaxed);
466-
} else if (exception() == Universe::out_of_memory_error_class_metaspace()) {
466+
} else if (Universe::is_out_of_memory_error_metaspace(exception())) {
467467
Atomic::inc(&_out_of_memory_error_class_metaspace_errors, memory_order_relaxed);
468468
} else {
469469
// everything else reported as java heap OOM
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright (c) 2021, Alibaba Group Holding Limited. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
25+
/*
26+
* @test
27+
* @bug 8278125
28+
* @summary Test if OOME has proper stacktrace
29+
* @library /test/lib
30+
* @run main/othervm -Xmx100m -Xms100m GenOutOfMemoryError
31+
*/
32+
33+
import jdk.test.lib.Asserts;
34+
35+
public class GenOutOfMemoryError {
36+
private static int OOME_HAS_STACK_CNT = 0;
37+
38+
private void badMethod(int n){
39+
try {
40+
System.out.format("bad method was invoked %n", n);
41+
// Try to allocate an array the same size as the heap - it will throw OOME without
42+
// actually consuming available memory.
43+
Integer[] array = new Integer[1000 * 1000 * 100];
44+
array.hashCode();
45+
} catch (Throwable t){
46+
StackTraceElement[] traces = t.getStackTrace();
47+
if (traces.length != 0) {
48+
OOME_HAS_STACK_CNT++;
49+
}
50+
t.printStackTrace();
51+
}
52+
}
53+
54+
public static void main(String[] args) {
55+
GenOutOfMemoryError genOutOfMemoryError = new GenOutOfMemoryError();
56+
57+
for (int i = 0; i < 7; i++) {
58+
genOutOfMemoryError.badMethod(i + 1);
59+
}
60+
Asserts.assertTrue(4/*PreallocatedOutOfMemoryErrorCount defaults to 4*/ == OOME_HAS_STACK_CNT, "Some OOMEs do not have stacktraces");
61+
}
62+
}

0 commit comments

Comments
 (0)
Please sign in to comment.