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

Print this page
rev 4168 : 8005602: NPG: classunloading does not happen while CMS GC with -XX:+CMSClassUnloadingEnabled is used
Summary: Call purge() on CLDG after sweep(), reorder purge() call in GenCollectedHeap and enable some additional logging
Reviewed-by:

*** 184,193 **** --- 184,199 ---- CMSParGCThreadState(CompactibleFreeListSpace* cfls) : lab(cfls) { promo.setSpace(cfls); } }; + class CMSPhaseTracing: public StackObj { + public: + CMSPhaseTracing(bool print, const char* phase); + ~CMSPhaseTracing(); + }; + ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration( ReservedSpace rs, size_t initial_byte_size, int level, CardTableRS* ct, bool use_adaptive_freelists, FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) : CardGeneration(rs, initial_byte_size, level, ct),
*** 2162,2175 **** // 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(); } ! // Used for PrintGC ! size_t prev_used; ! if (PrintGC && Verbose) { ! prev_used = _cmsGen->used(); // XXXPERM } // The change of the collection state is normally done at this level; // the exceptions are phases that are executed while the world is // stopped. For those phases the change of state is done while the --- 2168,2183 ---- // 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(); } ! // Used for PrintGCDetails ! size_t prev_used = 0; ! size_t metaspace_pre_unloading = 0; ! if (PrintGCDetails) { ! prev_used = _cmsGen->used(); ! metaspace_pre_unloading = MetaspaceAux::used_in_bytes(); } // The change of the collection state is normally done at this level; // the exceptions are phases that are executed while the world is // stopped. For those phases the change of state is done while the
*** 2316,2325 **** --- 2324,2342 ---- ReleaseForegroundGC x(this); // unblock FG collection MutexLockerEx y(Heap_lock, Mutex::_no_safepoint_check_flag); CMSTokenSync z(true); // not strictly needed. if (_collectorState == Resizing) { compute_new_size(); + if (PrintGCDetails) { + CMSPhaseTracing pt(true, "[CMS-resizing: "); + gclog_or_tty->print("[%s:", cmsGen()->short_name()); + cmsGen()->print_heap_change(prev_used); + gclog_or_tty->print("]"); + MetaspaceAux::print_metaspace_change(metaspace_pre_unloading); + gclog_or_tty->print_cr(" ]"); + } + _collectorState = Resetting; } else { assert(_collectorState == Idling, "The state should only change" " because the foreground collector has finished the collection"); }
*** 2369,2381 **** if (TraceCMSState) { gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT " exiting collection CMS state %d", Thread::current(), _collectorState); } - if (PrintGC && Verbose) { - _cmsGen->print_heap_change(prev_used); - } } void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) { assert(_foregroundGCIsActive && !_foregroundGCShouldWait, "Foreground collector should be waiting, not executing"); --- 2386,2395 ----
*** 3362,3375 **** // XXX Fix when compaction is implemented. warning("Shrinking of CMS not yet implemented"); return; } // Simple ctor/dtor wrapper for accounting & timer chores around concurrent // phases. ! class CMSPhaseAccounting: public StackObj { public: CMSPhaseAccounting(CMSCollector *collector, const char *phase, bool print_cr = true); ~CMSPhaseAccounting(); --- 3376,3398 ---- // XXX Fix when compaction is implemented. warning("Shrinking of CMS not yet implemented"); return; } + CMSPhaseTracing::CMSPhaseTracing(bool print, const char* phase) { + if (print) { + gclog_or_tty->date_stamp(PrintGCDateStamps); + gclog_or_tty->stamp(PrintGCTimeStamps); + gclog_or_tty->print("%s", phase); + } + } + + CMSPhaseTracing::~CMSPhaseTracing() {} // Simple ctor/dtor wrapper for accounting & timer chores around concurrent // phases. ! class CMSPhaseAccounting: public CMSPhaseTracing { public: CMSPhaseAccounting(CMSCollector *collector, const char *phase, bool print_cr = true); ~CMSPhaseAccounting();
*** 3393,3411 **** }; CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector, const char *phase, bool print_cr) : _collector(collector), _phase(phase), _print_cr(print_cr) { if (PrintCMSStatistics != 0) { _collector->resetYields(); } if (PrintGCDetails && PrintGCTimeStamps) { ! gclog_or_tty->date_stamp(PrintGCDateStamps); ! gclog_or_tty->stamp(); ! gclog_or_tty->print_cr(": [%s-concurrent-%s-start]", _collector->cmsGen()->short_name(), _phase); } _collector->resetTimer(); _wallclock.start(); _collector->startTimer(); --- 3416,3433 ---- }; CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector, const char *phase, bool print_cr) : + CMSPhaseTracing(PrintGCDetails, ""), _collector(collector), _phase(phase), _print_cr(print_cr) { if (PrintCMSStatistics != 0) { _collector->resetYields(); } if (PrintGCDetails && PrintGCTimeStamps) { ! gclog_or_tty->print_cr("[%s-concurrent-%s-start]", _collector->cmsGen()->short_name(), _phase); } _collector->resetTimer(); _wallclock.start(); _collector->startTimer();
*** 6071,6080 **** --- 6093,6106 ---- _collectorState = Resizing; } verify_work_stacks_empty(); verify_overflow_empty(); + if (should_unload_classes()) { + ClassLoaderDataGraph::purge(); + } + _intra_sweep_timer.stop(); _intra_sweep_estimate.sample(_intra_sweep_timer.seconds()); _inter_sweep_timer.reset(); _inter_sweep_timer.start();