src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp

Print this page
rev 4482 : 8013934: Garbage collection event for CMS has wrong cause for System.gc()

*** 61,70 **** --- 61,71 ---- #include "services/runtimeService.hpp" // statics CMSCollector* ConcurrentMarkSweepGeneration::_collector = NULL; bool CMSCollector::_full_gc_requested = false; + GCCause::Cause CMSCollector::_full_gc_cause = GCCause::_no_gc; ////////////////////////////////////////////////////////////////// // In support of CMS/VM thread synchronization ////////////////////////////////////////////////////////////////// // We split use of the CGC_lock into 2 "levels".
*** 1681,1696 **** acquire_control_and_collect(full, clear_all_soft_refs); _full_gcs_since_conc_gc++; } ! void CMSCollector::request_full_gc(unsigned int full_gc_count) { GenCollectedHeap* gch = GenCollectedHeap::heap(); unsigned int gc_count = gch->total_full_collections(); if (gc_count == full_gc_count) { MutexLockerEx y(CGC_lock, Mutex::_no_safepoint_check_flag); _full_gc_requested = true; CGC_lock->notify(); // nudge CMS thread } else { assert(gc_count > full_gc_count, "Error: causal loop"); } } --- 1682,1698 ---- acquire_control_and_collect(full, clear_all_soft_refs); _full_gcs_since_conc_gc++; } ! void CMSCollector::request_full_gc(unsigned int full_gc_count, GCCause::Cause cause) { GenCollectedHeap* gch = GenCollectedHeap::heap(); unsigned int gc_count = gch->total_full_collections(); if (gc_count == full_gc_count) { MutexLockerEx y(CGC_lock, Mutex::_no_safepoint_check_flag); _full_gc_requested = true; + _full_gc_cause = cause; CGC_lock->notify(); // nudge CMS thread } else { assert(gc_count > full_gc_count, "Error: causal loop"); } }
*** 2121,2131 **** // In the foreground case don't do the precleaning since // it is not done concurrently and there is extra work // required. _collectorState = FinalMarking; } ! collect_in_foreground(clear_all_soft_refs); // For a mark-sweep, compute_new_size() will be called // in the heap's do_collection() method. } --- 2123,2133 ---- // In the foreground case don't do the precleaning since // it is not done concurrently and there is extra work // required. _collectorState = FinalMarking; } ! collect_in_foreground(clear_all_soft_refs, GenCollectedHeap::heap()->gc_cause()); // For a mark-sweep, compute_new_size() will be called // in the heap's do_collection() method. }
*** 2184,2194 **** // the different locking requirements of the background collector and the // foreground collector. There was originally an attempt to share // one "collect" method between the background collector and the foreground // collector but the if-then-else required made it cleaner to have // separate methods. ! void CMSCollector::collect_in_background(bool clear_all_soft_refs) { assert(Thread::current()->is_ConcurrentGC_thread(), "A CMS asynchronous collection is only allowed on a CMS thread."); GenCollectedHeap* gch = GenCollectedHeap::heap(); { --- 2186,2196 ---- // the different locking requirements of the background collector and the // foreground collector. There was originally an attempt to share // one "collect" method between the background collector and the foreground // collector but the if-then-else required made it cleaner to have // separate methods. ! void CMSCollector::collect_in_background(bool clear_all_soft_refs, GCCause::Cause cause) { assert(Thread::current()->is_ConcurrentGC_thread(), "A CMS asynchronous collection is only allowed on a CMS thread."); GenCollectedHeap* gch = GenCollectedHeap::heap(); {
*** 2203,2221 **** assert(!_foregroundGCShouldWait, "Should be clear"); return; } else { assert(_collectorState == Idling, "Should be idling before start."); _collectorState = InitialMarking; ! register_gc_start(GCCause::_cms_concurrent_mark); // Reset the expansion cause, now that we are about to begin // a new cycle. clear_expansion_cause(); } // Decide if we want to enable class unloading as part of the // ensuing concurrent GC cycle. update_should_unload_classes(); _full_gc_requested = false; // acks all outstanding full gc requests // Signal that we are about to start a collection gch->increment_total_full_collections(); // ... starting a collection cycle _collection_count_start = gch->total_full_collections(); } --- 2205,2224 ---- assert(!_foregroundGCShouldWait, "Should be clear"); return; } else { assert(_collectorState == Idling, "Should be idling before start."); _collectorState = InitialMarking; ! register_gc_start(cause); // Reset the expansion cause, now that we are about to begin // a new cycle. clear_expansion_cause(); } // Decide if we want to enable class unloading as part of the // ensuing concurrent GC cycle. update_should_unload_classes(); _full_gc_requested = false; // acks all outstanding full gc requests + _full_gc_cause = GCCause::_no_gc; // Signal that we are about to start a collection gch->increment_total_full_collections(); // ... starting a collection cycle _collection_count_start = gch->total_full_collections(); }
*** 2458,2468 **** void CMSCollector::report_heap_summary(GCWhen::Type when) { _gc_tracer_cm->report_gc_heap_summary(when, _last_heap_summary, _last_perm_gen_summary); } ! void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) { assert(_foregroundGCIsActive && !_foregroundGCShouldWait, "Foreground collector should be waiting, not executing"); assert(Thread::current()->is_VM_thread(), "A foreground collection" "may only be done by the VM Thread with the world stopped"); assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(), --- 2461,2471 ---- void CMSCollector::report_heap_summary(GCWhen::Type when) { _gc_tracer_cm->report_gc_heap_summary(when, _last_heap_summary, _last_perm_gen_summary); } ! void CMSCollector::collect_in_foreground(bool clear_all_soft_refs, GCCause::Cause cause) { assert(_foregroundGCIsActive && !_foregroundGCShouldWait, "Foreground collector should be waiting, not executing"); assert(Thread::current()->is_VM_thread(), "A foreground collection" "may only be done by the VM Thread with the world stopped"); assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
*** 2491,2501 **** gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " in CMS state %d", Thread::current(), _collectorState); } switch (_collectorState) { case InitialMarking: ! register_foreground_gc_start(GenCollectedHeap::heap()->gc_cause()); init_mark_was_synchronous = true; // fact to be exploited in re-mark checkpointRootsInitial(false); assert(_collectorState == Marking, "Collector state should have changed" " within checkpointRootsInitial()"); break; --- 2494,2504 ---- gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " in CMS state %d", Thread::current(), _collectorState); } switch (_collectorState) { case InitialMarking: ! register_foreground_gc_start(cause); init_mark_was_synchronous = true; // fact to be exploited in re-mark checkpointRootsInitial(false); assert(_collectorState == Marking, "Collector state should have changed" " within checkpointRootsInitial()"); break;