void VM_GenCollectFullConcurrent::doit_epilogue() { Thread* thr = Thread::current(); assert(thr->is_Java_thread(), "just checking"); JavaThread* jt = (JavaThread*)thr; // Release the Heap_lock first. Heap_lock->unlock(); release_and_notify_pending_list_lock(); // It is fine to test whether completed collections has // exceeded our request count without locking because // the completion count is monotonically increasing; // this will break for very long-running apps when the // count overflows and wraps around. XXX fix me !!! // e.g. at the rate of 1 full gc per ms, this could // overflow in about 1000 years. GenCollectedHeap* gch = GenCollectedHeap::heap(); if (gch->total_full_collections_completed() <= _full_gc_count_before) { // Now, wait for witnessing concurrent gc cycle to complete, // but do so in native mode, because we want to lock the // FullGCEvent_lock, which may be needed by the VM thread // or by the CMS thread, so we do not want to be suspended // while holding that lock. ThreadToNativeFromVM native(jt); MutexLockerEx ml(FullGCCount_lock, Mutex::_no_safepoint_check_flag); // Either a concurrent or a stop-world full gc is sufficient // witness to our request. while (gch->total_full_collections_completed() <= _full_gc_count_before) { FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag); } } // Enable iCMS back. CMSCollector::enable_icms(); }
void VM_GenCollectFullConcurrent::doit_epilogue() { Thread* thr = Thread::current(); assert(thr->is_Java_thread(), "just checking"); JavaThread* jt = (JavaThread*)thr; if (Universe::has_reference_pending_list()) { Heap_lock->notify_all(); } Heap_lock->unlock(); // It is fine to test whether completed collections has // exceeded our request count without locking because // the completion count is monotonically increasing; // this will break for very long-running apps when the // count overflows and wraps around. XXX fix me !!! // e.g. at the rate of 1 full gc per ms, this could // overflow in about 1000 years. GenCollectedHeap* gch = GenCollectedHeap::heap(); if (_gc_cause != GCCause::_gc_locker && gch->total_full_collections_completed() <= _full_gc_count_before) { // maybe we should change the condition to test _gc_cause == // GCCause::_java_lang_system_gc or GCCause::_dcmd_gc_run, // instead of _gc_cause != GCCause::_gc_locker assert(GCCause::is_user_requested_gc(_gc_cause), "the only way to get here if this was a System.gc()-induced GC"); assert(ExplicitGCInvokesConcurrent, "Error"); // Now, wait for witnessing concurrent gc cycle to complete, // but do so in native mode, because we want to lock the // FullGCEvent_lock, which may be needed by the VM thread // or by the CMS thread, so we do not want to be suspended // while holding that lock. ThreadToNativeFromVM native(jt); MutexLockerEx ml(FullGCCount_lock, Mutex::_no_safepoint_check_flag); // Either a concurrent or a stop-world full gc is sufficient // witness to our request. while (gch->total_full_collections_completed() <= _full_gc_count_before) { FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag); } } }