--- old/src/hotspot/share/memory/metaspaceShared.cpp 2020-06-08 15:04:01.547243681 -0700 +++ new/src/hotspot/share/memory/metaspaceShared.cpp 2020-06-08 15:04:01.411238562 -0700 @@ -36,6 +36,7 @@ #include "classfile/systemDictionary.hpp" #include "classfile/systemDictionaryShared.hpp" #include "code/codeCache.hpp" +#include "gc/shared/gcLocker.hpp" #include "gc/shared/softRefPolicy.hpp" #include "interpreter/bytecodeStream.hpp" #include "interpreter/bytecodes.hpp" @@ -1229,6 +1230,7 @@ void print_heap_region_stats(GrowableArray *heap_mem, const char *name, size_t total_size); void relocate_to_requested_base_address(CHeapBitMap* ptrmap); + void run_gc(); public: @@ -1636,7 +1638,26 @@ } } +void VM_PopulateDumpSharedSpace::run_gc() { + if (HeapShared::is_heap_object_archiving_allowed()) { + // Avoid fragmentation while archiving heap objects. + // We do this inside a safepoint, so that no further allocation can happen after GC + // has finished. + if (GCLocker::is_active()) { + // This should not happen during -Xshare:dump. If you see this, probably the Java core lib + // has been modified such that JNI code is executed in some clean up threads after + // we have finished class loading. + log_warning(cds)("GC locker is held; GC is skipped. This may produce suboptimal archive heap regions."); + } else { + log_info(cds)("Run GC ..."); + Universe::heap()->collect_as_vm_thread(GCCause::_archive_time_gc); + log_info(cds)("Run GC done"); + } + } +} + void VM_PopulateDumpSharedSpace::doit() { + run_gc(); CHeapBitMap ptrmap; MetaspaceShared::initialize_ptr_marker(&ptrmap); @@ -1955,14 +1976,9 @@ link_and_cleanup_shared_classes(CATCH); log_info(cds)("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; + MutexLocker ml(THREAD, HeapShared::is_heap_object_archiving_allowed() ? + Heap_lock : NULL); // needed for collect_as_vm_thread VMThread::execute(&op); } }