< prev index next >

src/hotspot/share/gc/g1/g1YoungRemSetSamplingThread.cpp

Print this page
rev 52572 : JDK-8212657: Implementation of JDK-8204089 Promptly Return Unused Committed Memory from G1
Summary: Issue optional, default enabled, concurrent cycles when the VM is idle to reclaim unused internal and Java heap memory.
Reviewed-by:
Contributed-by: Rodrigo Bruno <rbruno@gsd.inesc-id.pt>, Ruslan Synytsky <rs@jelastic.com>, Thomas Schatzl <thomas.schatzl@oracle.com>
rev 52573 : [mq]: 8212657-stefanj-review

*** 23,32 **** --- 23,34 ---- */ #include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectionSet.hpp" + #include "gc/g1/g1ConcurrentMark.inline.hpp" + #include "gc/g1/g1ConcurrentMarkThread.inline.hpp" #include "gc/g1/g1Policy.hpp" #include "gc/g1/g1YoungRemSetSamplingThread.hpp" #include "gc/g1/heapRegion.inline.hpp" #include "gc/g1/heapRegionRemSet.hpp" #include "gc/shared/suspendibleThreadSet.hpp"
*** 35,57 **** G1YoungRemSetSamplingThread::G1YoungRemSetSamplingThread() : ConcurrentGCThread(), _monitor(Mutex::nonleaf, "G1YoungRemSetSamplingThread monitor", true, ! Monitor::_safepoint_check_never) { set_name("G1 Young RemSet Sampling"); create_and_start(); } void G1YoungRemSetSamplingThread::sleep_before_next_cycle() { MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag); if (!should_terminate()) { ! uintx waitms = G1ConcRefinementServiceIntervalMillis; // 300, really should be? _monitor.wait(Mutex::_no_safepoint_check_flag, waitms); } } void G1YoungRemSetSamplingThread::run_service() { double vtime_start = os::elapsedVTime(); while (!should_terminate()) { sample_young_list_rs_lengths(); --- 37,98 ---- G1YoungRemSetSamplingThread::G1YoungRemSetSamplingThread() : ConcurrentGCThread(), _monitor(Mutex::nonleaf, "G1YoungRemSetSamplingThread monitor", true, ! Monitor::_safepoint_check_never), ! _last_periodic_gc_attempt_s(os::elapsedTime()) { set_name("G1 Young RemSet Sampling"); create_and_start(); } void G1YoungRemSetSamplingThread::sleep_before_next_cycle() { MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag); if (!should_terminate()) { ! uintx waitms = G1ConcRefinementServiceIntervalMillis; _monitor.wait(Mutex::_no_safepoint_check_flag, waitms); } } + bool G1YoungRemSetSamplingThread::should_start_periodic_gc() { + // If we are currently in a concurrent mark we are going to uncommit memory soon. + if (G1CollectedHeap::heap()->concurrent_mark()->cm_thread()->during_cycle()) { + log_debug(gc, periodic)("Concurrent cycle in progress. Skipping."); + return false; + } + + // Check if enough time has passed since the last GC. + uintx time_since_last_gc; + if ((G1PeriodicGCInterval == 0) || + ((time_since_last_gc = (uintx)Universe::heap()->millis_since_last_gc()) < G1PeriodicGCInterval)) { + log_debug(gc, periodic)("Last GC occurred " UINTX_FORMAT "ms before which is below threshold " UINTX_FORMAT "ms. Skipping.", + time_since_last_gc, G1PeriodicGCInterval); + return false; + } + + // Check if load is lower than max. + double recent_load; + if ((G1PeriodicGCSystemLoadThreshold > 0) && + (os::loadavg(&recent_load, 1) == -1 || recent_load > G1PeriodicGCSystemLoadThreshold)) { + log_debug(gc, periodic)("Load %1.2f is higher than threshold " UINTX_FORMAT ". Skipping.", + recent_load, G1PeriodicGCSystemLoadThreshold); + return false; + } + + return true; + } + + void G1YoungRemSetSamplingThread::check_for_periodic_gc(){ + if ((os::elapsedTime() - _last_periodic_gc_attempt_s) > (G1PeriodicGCInterval / 1000.0)) { + log_debug(gc, periodic)("Checking for periodic GC."); + if (should_start_periodic_gc()) { + Universe::heap()->collect(GCCause::_g1_periodic_collection); + } + _last_periodic_gc_attempt_s = os::elapsedTime(); + } + } + void G1YoungRemSetSamplingThread::run_service() { double vtime_start = os::elapsedVTime(); while (!should_terminate()) { sample_young_list_rs_lengths();
*** 60,69 **** --- 101,112 ---- _vtime_accum = (os::elapsedVTime() - vtime_start); } else { _vtime_accum = 0.0; } + check_for_periodic_gc(); + sleep_before_next_cycle(); } } void G1YoungRemSetSamplingThread::stop_service() {
< prev index next >