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,10 +184,16 @@
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,14 +2168,16 @@
// 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
+ // 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,10 +2324,19 @@
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,13 +2386,10 @@
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");
@@ -3362,14 +3376,23 @@
// 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 StackObj {
+class CMSPhaseAccounting: public CMSPhaseTracing {
public:
CMSPhaseAccounting(CMSCollector *collector,
const char *phase,
bool print_cr = true);
~CMSPhaseAccounting();
@@ -3393,19 +3416,18 @@
};
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->date_stamp(PrintGCDateStamps);
- gclog_or_tty->stamp();
- gclog_or_tty->print_cr(": [%s-concurrent-%s-start]",
+ gclog_or_tty->print_cr("[%s-concurrent-%s-start]",
_collector->cmsGen()->short_name(), _phase);
}
_collector->resetTimer();
_wallclock.start();
_collector->startTimer();
@@ -6071,10 +6093,14 @@
_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();