# HG changeset patch # User jwilhelm # Date 1458806024 -3600 # Thu Mar 24 08:53:44 2016 +0100 # Node ID 891644f15aa1c2d65a777a1806761d6b8b7f1f7e # Parent edeb8dc8ff14d2d37be5690dc9802e4fe8ceb088 8114823: G1 doesn't honor request to disable class unloading Reviewed-by: mgerdin, stefank * * * [mq]: autocreated-1708 diff --git a/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp b/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp --- a/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp +++ b/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp @@ -479,7 +479,7 @@ _verification_mark_bm(0, Mutex::leaf + 1, "CMS_verification_mark_bm_lock"), _completed_initialization(false), _collector_policy(cp), - _should_unload_classes(CMSClassUnloadingEnabled), + _should_unload_classes(ClassUnloadingWithConcurrentMark), _concurrent_cycles_since_last_unload(0), _roots_scanning_options(GenCollectedHeap::SO_None), _inter_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding), @@ -2562,7 +2562,7 @@ // Condition 1 above if (_full_gc_requested && ExplicitGCInvokesConcurrentAndUnloadsClasses) { _should_unload_classes = true; - } else if (CMSClassUnloadingEnabled) { // Condition 2.a above + } else if (ClassUnloadingWithConcurrentMark) { // Condition 2.a above // Disjuncts 2.b.(i,ii,iii) above _should_unload_classes = (concurrent_cycles_since_last_unload() >= CMSClassUnloadingMaxInterval) diff --git a/src/share/vm/gc/g1/g1MarkSweep.cpp b/src/share/vm/gc/g1/g1MarkSweep.cpp --- a/src/share/vm/gc/g1/g1MarkSweep.cpp +++ b/src/share/vm/gc/g1/g1MarkSweep.cpp @@ -130,11 +130,16 @@ ClassLoaderDataGraph::clear_claimed_marks(); MarkingCodeBlobClosure follow_code_closure(&GenMarkSweep::follow_root_closure, !CodeBlobToOopClosure::FixRelocations); - { + if (ClassUnloading) { G1RootProcessor root_processor(g1h, 1); root_processor.process_strong_roots(&GenMarkSweep::follow_root_closure, &GenMarkSweep::follow_cld_closure, &follow_code_closure); + } else { + G1RootProcessor root_processor(g1h, 1); + root_processor.process_all_roots(&GenMarkSweep::follow_root_closure, + &GenMarkSweep::follow_cld_closure, + &follow_code_closure); } { @@ -157,7 +162,7 @@ // This is the point where the entire marking should have completed. assert(GenMarkSweep::_marking_stack.is_empty(), "Marking should have completed"); - { + if (ClassUnloading) { GCTraceTime(Debug, gc, phases) trace("Class Unloading", gc_timer()); // Unload classes and purge the SystemDictionary. diff --git a/src/share/vm/gc/parallel/psMarkSweep.cpp b/src/share/vm/gc/parallel/psMarkSweep.cpp --- a/src/share/vm/gc/parallel/psMarkSweep.cpp +++ b/src/share/vm/gc/parallel/psMarkSweep.cpp @@ -534,7 +534,7 @@ // This is the point where the entire marking should have completed. assert(_marking_stack.is_empty(), "Marking should have completed"); - { + if (ClassUnloading) { GCTraceTime(Debug, gc, phases) t("Class Unloading", _gc_timer); // Unload classes and purge the SystemDictionary. @@ -545,8 +545,13 @@ // Prune dead klasses from subklass/sibling/implementor lists. Klass::clean_weak_klass_links(is_alive_closure()); + } else { + // Unload nmethods. + GCTraceTime(Debug, gc, phases) t("NMethod Unloading", _gc_timer); + CodeCache::do_unloading(is_alive_closure(), false); } + { GCTraceTime(Debug, gc, phases) t("Scrub String Table", _gc_timer); // Delete entries for dead interned strings. diff --git a/src/share/vm/gc/parallel/psParallelCompact.cpp b/src/share/vm/gc/parallel/psParallelCompact.cpp --- a/src/share/vm/gc/parallel/psParallelCompact.cpp +++ b/src/share/vm/gc/parallel/psParallelCompact.cpp @@ -2107,7 +2107,7 @@ // This is the point where the entire marking should have completed. assert(cm->marking_stacks_empty(), "Marking should have completed"); - { + if (ClassUnloading) { GCTraceTime(Debug, gc, phases) tm_m("Class Unloading", &_gc_timer); // Follow system dictionary roots and unload classes. @@ -2118,6 +2118,10 @@ // Prune dead klasses from subklass/sibling/implementor lists. Klass::clean_weak_klass_links(is_alive_closure()); + } else { + // Unload nmethods. + GCTraceTime(Debug, gc, phases) tm_m("NMethod Unloading", &_gc_timer); + CodeCache::do_unloading(is_alive_closure(), false); } { diff --git a/src/share/vm/gc/serial/genMarkSweep.cpp b/src/share/vm/gc/serial/genMarkSweep.cpp --- a/src/share/vm/gc/serial/genMarkSweep.cpp +++ b/src/share/vm/gc/serial/genMarkSweep.cpp @@ -220,7 +220,7 @@ // This is the point where the entire marking should have completed. assert(_marking_stack.is_empty(), "Marking should have completed"); - { + if (ClassUnloading) { GCTraceTime(Debug, gc, phases) tm_m("Class Unloading", gc_timer()); // Unload classes and purge the SystemDictionary. @@ -231,6 +231,10 @@ // Prune dead klasses from subklass/sibling/implementor lists. Klass::clean_weak_klass_links(&is_alive); + } else { + // Unload nmethods. + GCTraceTime(Debug, gc, phases) tm_m("NMethod Unloading", gc_timer()); + CodeCache::do_unloading(&is_alive, false); } { diff --git a/src/share/vm/gc/shared/vmGCOperations.cpp b/src/share/vm/gc/shared/vmGCOperations.cpp --- a/src/share/vm/gc/shared/vmGCOperations.cpp +++ b/src/share/vm/gc/shared/vmGCOperations.cpp @@ -201,7 +201,7 @@ // Returns true iff concurrent GCs unloads metadata. bool VM_CollectForMetadataAllocation::initiate_concurrent_GC() { #if INCLUDE_ALL_GCS - if (UseConcMarkSweepGC && CMSClassUnloadingEnabled) { + if (UseConcMarkSweepGC && ClassUnloadingWithConcurrentMark) { MetaspaceGC::set_should_concurrent_collect(true); return true; } diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp +++ b/src/share/vm/runtime/arguments.cpp @@ -404,6 +404,7 @@ { "ParallelMarkingThreads", "ConcGCThreads" }, { "ParallelCMSThreads", "ConcGCThreads" }, { "CreateMinidumpOnCrash", "CreateCoredumpOnCrash" }, + { "CMSClassUnloadingEnabled", "ClassUnloadingWithConcurrentMark" }, { NULL, NULL} }; @@ -1825,11 +1826,6 @@ CompactibleFreeListSpaceLAB::modify_initialization(OldPLABSize, OldPLABWeight); } - if (!ClassUnloading) { - FLAG_SET_CMDLINE(bool, CMSClassUnloadingEnabled, false); - FLAG_SET_CMDLINE(bool, ExplicitGCInvokesConcurrentAndUnloadsClasses, false); - } - log_trace(gc)("MarkStackSize: %uk MarkStackSizeMax: %uk", (unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K)); log_trace(gc)("ConcGCThreads: %u", ConcGCThreads); } @@ -2163,6 +2159,11 @@ // Keeping the heap 100% free is hard ;-) so limit it to 99%. FLAG_SET_ERGO(uintx, MinHeapFreeRatio, 99); } + + if (!ClassUnloading) { + FLAG_SET_CMDLINE(bool, ClassUnloadingWithConcurrentMark, false); + FLAG_SET_CMDLINE(bool, ExplicitGCInvokesConcurrentAndUnloadsClasses, false); + } #endif // INCLUDE_ALL_GCS } diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp +++ b/src/share/vm/runtime/globals.hpp @@ -1748,9 +1748,6 @@ "duration exceeds this threshold in milliseconds") \ range(0, max_uintx) \ \ - product(bool, CMSClassUnloadingEnabled, true, \ - "Whether class unloading enabled when using CMS GC") \ - \ product(uintx, CMSClassUnloadingMaxInterval, 0, \ "When CMS class unloading is enabled, the maximum CMS cycle " \ "count for which classes may not be unloaded") \