mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 18:44:38 +02:00
8214388: CDS dumping fails with java heap fragmentation
Force a full GC with a single thread before writing heap archive regions Reviewed-by: sjohanss, jiangli
This commit is contained in:
parent
ea532aa075
commit
a0a108fb01
19 changed files with 489 additions and 35 deletions
|
@ -29,6 +29,7 @@
|
|||
#include "classfile/classLoaderExt.hpp"
|
||||
#include "classfile/dictionary.hpp"
|
||||
#include "classfile/loaderConstraints.hpp"
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "classfile/placeholders.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
|
@ -350,7 +351,11 @@ void MetaspaceShared::post_initialize(TRAPS) {
|
|||
}
|
||||
}
|
||||
|
||||
static GrowableArray<Handle>* _extra_interned_strings = NULL;
|
||||
|
||||
void MetaspaceShared::read_extra_data(const char* filename, TRAPS) {
|
||||
_extra_interned_strings = new (ResourceObj::C_HEAP, mtInternal)GrowableArray<Handle>(10000, true);
|
||||
|
||||
HashtableTextDump reader(filename);
|
||||
reader.check_version("VERSION: 1.0");
|
||||
|
||||
|
@ -358,15 +363,45 @@ void MetaspaceShared::read_extra_data(const char* filename, TRAPS) {
|
|||
int utf8_length;
|
||||
int prefix_type = reader.scan_prefix(&utf8_length);
|
||||
ResourceMark rm(THREAD);
|
||||
char* utf8_buffer = NEW_RESOURCE_ARRAY(char, utf8_length);
|
||||
if (utf8_length == 0x7fffffff) {
|
||||
// buf_len will overflown 32-bit value.
|
||||
vm_exit_during_initialization(err_msg("string length too large: %d", utf8_length));
|
||||
}
|
||||
int buf_len = utf8_length+1;
|
||||
char* utf8_buffer = NEW_RESOURCE_ARRAY(char, buf_len);
|
||||
reader.get_utf8(utf8_buffer, utf8_length);
|
||||
utf8_buffer[utf8_length] = '\0';
|
||||
|
||||
if (prefix_type == HashtableTextDump::SymbolPrefix) {
|
||||
SymbolTable::new_symbol(utf8_buffer, utf8_length, THREAD);
|
||||
SymbolTable::new_permanent_symbol(utf8_buffer, THREAD);
|
||||
} else{
|
||||
assert(prefix_type == HashtableTextDump::StringPrefix, "Sanity");
|
||||
utf8_buffer[utf8_length] = '\0';
|
||||
oop s = StringTable::intern(utf8_buffer, THREAD);
|
||||
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
log_warning(cds, heap)("[line %d] extra interned string allocation failed; size too large: %d",
|
||||
reader.last_line_no(), utf8_length);
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
} else {
|
||||
#if INCLUDE_G1GC
|
||||
if (UseG1GC) {
|
||||
typeArrayOop body = java_lang_String::value(s);
|
||||
const HeapRegion* hr = G1CollectedHeap::heap()->heap_region_containing(body);
|
||||
if (hr->is_humongous()) {
|
||||
// Don't keep it alive, so it will be GC'ed before we dump the strings, in order
|
||||
// to maximize free heap space and minimize fragmentation.
|
||||
log_warning(cds, heap)("[line %d] extra interned string ignored; size too large: %d",
|
||||
reader.last_line_no(), utf8_length);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Interned strings are GC'ed if there are no references to it, so let's
|
||||
// add a reference to keep this string alive.
|
||||
assert(s != NULL, "must succeed");
|
||||
Handle h(THREAD, s);
|
||||
_extra_interned_strings->append(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -451,8 +486,6 @@ address MetaspaceShared::cds_i2i_entry_code_buffers(size_t total_size) {
|
|||
return _cds_i2i_entry_code_buffers;
|
||||
}
|
||||
|
||||
// CDS code for dumping shared archive.
|
||||
|
||||
// Global object for holding classes that have been loaded. Since this
|
||||
// is run at a safepoint just before exit, this is the entire set of classes.
|
||||
static GrowableArray<Klass*>* _global_klass_objects;
|
||||
|
@ -1686,6 +1719,13 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
|
|||
link_and_cleanup_shared_classes(CATCH);
|
||||
tty->print_cr("Rewriting and linking classes: done");
|
||||
|
||||
if (HeapShared::is_heap_object_archiving_allowed()) {
|
||||
// Avoid fragmentation while archiving heap objects.
|
||||
Universe::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(true);
|
||||
Universe::heap()->collect(GCCause::_archive_time_gc);
|
||||
Universe::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(false);
|
||||
}
|
||||
|
||||
VM_PopulateDumpSharedSpace op;
|
||||
VMThread::execute(&op);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue