< prev index next >

src/hotspot/share/memory/metaspace.cpp

Print this page

        

*** 21,33 **** * questions. * */ #include "precompiled.hpp" #include "aot/aotLoader.hpp" #include "gc/shared/collectedHeap.hpp" ! #include "gc/shared/collectorPolicy.hpp" ! #include "gc/shared/gcLocker.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/allocation.hpp" #include "memory/binaryTreeDictionary.hpp" #include "memory/filemap.hpp" --- 21,34 ---- * questions. * */ #include "precompiled.hpp" #include "aot/aotLoader.hpp" + #include "classfile/classLoaderData.hpp" #include "gc/shared/collectedHeap.hpp" ! #include "gc/shared/gcLocker.inline.hpp" ! #include "gc/shared/vmGCOperations.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/allocation.hpp" #include "memory/binaryTreeDictionary.hpp" #include "memory/filemap.hpp"
*** 43,52 **** --- 44,54 ---- #include "runtime/globals.hpp" #include "runtime/init.hpp" #include "runtime/java.hpp" #include "runtime/mutex.hpp" #include "runtime/orderAccess.inline.hpp" + #include "runtime/vmThread.hpp" #include "services/memTracker.hpp" #include "services/memoryService.hpp" #include "utilities/align.hpp" #include "utilities/copy.hpp" #include "utilities/debug.hpp"
*** 1819,1828 **** --- 1821,1904 ---- new_capacity_until_GC, MetaspaceGCThresholdUpdater::ComputeNewSize); } } + MetaWord* MetaspaceGC::satisfy_failed_metadata_allocation(ClassLoaderData* loader_data, + size_t word_size, + Metaspace::MetadataType mdtype) { + uint loop_count = 0; + uint gc_count = 0; + uint full_gc_count = 0; + + assert(!Heap_lock->owned_by_self(), "Should not be holding the Heap_lock"); + + do { + MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype); + if (result != NULL) { + return result; + } + + if (GCLocker::is_active_and_needs_gc()) { + // If the GCLocker is active, just expand and allocate. + // If that does not succeed, wait if this thread is not + // in a critical section itself. + result = loader_data->metaspace_non_null()->expand_and_allocate(word_size, mdtype); + if (result != NULL) { + return result; + } + JavaThread* jthr = JavaThread::current(); + if (!jthr->in_critical()) { + // Wait for JNI critical section to be exited + GCLocker::stall_until_clear(); + // The GC invoked by the last thread leaving the critical + // section will be a young collection and a full collection + // is (currently) needed for unloading classes so continue + // to the next iteration to get a full GC. + continue; + } else { + if (CheckJNICalls) { + fatal("Possible deadlock due to allocating while" + " in jni critical section"); + } + return NULL; + } + } + + { // Need lock to get self consistent gc_count's + MutexLocker ml(Heap_lock); + gc_count = Universe::heap()->total_collections(); + full_gc_count = Universe::heap()->total_full_collections(); + } + + // Generate a VM operation + VM_CollectForMetadataAllocation op(loader_data, + word_size, + mdtype, + gc_count, + full_gc_count, + GCCause::_metadata_GC_threshold); + VMThread::execute(&op); + + // If GC was locked out, try again. Check before checking success because the + // prologue could have succeeded and the GC still have been locked out. + if (op.gc_locked()) { + continue; + } + + if (op.prologue_succeeded()) { + return op.result(); + } + loop_count++; + if ((QueuedAllocationWarningCount > 0) && + (loop_count % QueuedAllocationWarningCount == 0)) { + log_warning(gc, ergo)("satisfy_failed_metadata_allocation() retries %d times," + " size=" SIZE_FORMAT, loop_count, word_size); + } + } while (true); // Until a GC is done + } + // Metadebug methods void Metadebug::init_allocation_fail_alot_count() { if (MetadataAllocationFailALot) { _allocation_fail_alot_count =
*** 3950,3961 **** // Allocation failed. if (is_init_completed()) { // Only start a GC if the bootstrapping has completed. // Try to clean out some memory and retry. ! result = Universe::heap()->collector_policy()->satisfy_failed_metadata_allocation( ! loader_data, word_size, mdtype); } } if (result == NULL) { SpaceManager* sm; --- 4026,4036 ---- // Allocation failed. if (is_init_completed()) { // Only start a GC if the bootstrapping has completed. // Try to clean out some memory and retry. ! result = Universe::heap()->satisfy_failed_metadata_allocation(loader_data, word_size, mdtype); } } if (result == NULL) { SpaceManager* sm;
< prev index next >