diff --git a/src/hotspot/share/services/attachListener.cpp b/src/hotspot/share/services/attachListener.cpp index 40b1a744018..d1531e1ec01 100644 --- a/src/hotspot/share/services/attachListener.cpp +++ b/src/hotspot/share/services/attachListener.cpp @@ -254,7 +254,7 @@ static jint dump_heap(AttachOperation* op, outputStream* out) { // This helps reduces the amount of unreachable objects in the dump // and makes it easier to browse. HeapDumper dumper(live_objects_only /* request GC */); - dumper.dump(path, out, level, false, HeapDumper::default_num_of_dump_threads()); + dumper.dump(path, out, level); } return JNI_OK; } diff --git a/src/hotspot/share/services/heapDumper.cpp b/src/hotspot/share/services/heapDumper.cpp index c28f1021540..eb568304dc0 100644 --- a/src/hotspot/share/services/heapDumper.cpp +++ b/src/hotspot/share/services/heapDumper.cpp @@ -2604,6 +2604,18 @@ int HeapDumper::dump(const char* path, outputStream* out, int compression, bool out->print_cr("Dumping heap to %s ...", path); timer()->start(); } + + if (_oome && num_dump_threads > 1) { + // Each additional parallel writer requires several MB of internal memory + // (DumpWriter buffer, DumperClassCacheTable, GZipCompressor buffers). + // For the OOM handling we may already be limited in memory. + // Lets ensure we have at least 20MB per thread. + julong max_threads = os::free_memory() / (20 * M); + if (num_dump_threads > max_threads) { + num_dump_threads = MAX2(1, (uint)max_threads); + } + } + // create JFR event EventHeapDump event; diff --git a/src/hotspot/share/services/heapDumper.hpp b/src/hotspot/share/services/heapDumper.hpp index bfc31b2f231..a69cf72aaf0 100644 --- a/src/hotspot/share/services/heapDumper.hpp +++ b/src/hotspot/share/services/heapDumper.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,8 +60,8 @@ class HeapDumper : public StackObj { // dumps the heap to the specified file, returns 0 if success. // additional info is written to out if not null. // compression >= 0 creates a gzipped file with the given compression level. - // parallel_thread_num >= 0 indicates thread numbers of parallel object dump - int dump(const char* path, outputStream* out = nullptr, int compression = -1, bool overwrite = false, uint parallel_thread_num = 1); + // parallel_thread_num >= 0 indicates thread numbers of parallel object dump. + int dump(const char* path, outputStream* out = nullptr, int compression = -1, bool overwrite = false, uint parallel_thread_num = default_num_of_dump_threads()); // returns error message (resource allocated), or null if no error char* error_as_C_string() const;