src/hotspot/share/gc/g1/g1YoungRemSetSamplingThread.cpp
changeset 52918 f94c7929a44b
parent 48969 7eb296a8ce2c
child 53034 de99beff5c0e
child 53090 759266b1c89b
equal deleted inserted replaced
52917:0c637249d934 52918:f94c7929a44b
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "gc/g1/g1CollectedHeap.inline.hpp"
    26 #include "gc/g1/g1CollectedHeap.inline.hpp"
    27 #include "gc/g1/g1CollectionSet.hpp"
    27 #include "gc/g1/g1CollectionSet.hpp"
       
    28 #include "gc/g1/g1ConcurrentMark.inline.hpp"
       
    29 #include "gc/g1/g1ConcurrentMarkThread.inline.hpp"
    28 #include "gc/g1/g1Policy.hpp"
    30 #include "gc/g1/g1Policy.hpp"
    29 #include "gc/g1/g1YoungRemSetSamplingThread.hpp"
    31 #include "gc/g1/g1YoungRemSetSamplingThread.hpp"
    30 #include "gc/g1/heapRegion.inline.hpp"
    32 #include "gc/g1/heapRegion.inline.hpp"
    31 #include "gc/g1/heapRegionRemSet.hpp"
    33 #include "gc/g1/heapRegionRemSet.hpp"
    32 #include "gc/shared/suspendibleThreadSet.hpp"
    34 #include "gc/shared/suspendibleThreadSet.hpp"
    35 G1YoungRemSetSamplingThread::G1YoungRemSetSamplingThread() :
    37 G1YoungRemSetSamplingThread::G1YoungRemSetSamplingThread() :
    36     ConcurrentGCThread(),
    38     ConcurrentGCThread(),
    37     _monitor(Mutex::nonleaf,
    39     _monitor(Mutex::nonleaf,
    38              "G1YoungRemSetSamplingThread monitor",
    40              "G1YoungRemSetSamplingThread monitor",
    39              true,
    41              true,
    40              Monitor::_safepoint_check_never) {
    42              Monitor::_safepoint_check_never),
       
    43     _last_periodic_gc_attempt_s(os::elapsedTime()) {
    41   set_name("G1 Young RemSet Sampling");
    44   set_name("G1 Young RemSet Sampling");
    42   create_and_start();
    45   create_and_start();
    43 }
    46 }
    44 
    47 
    45 void G1YoungRemSetSamplingThread::sleep_before_next_cycle() {
    48 void G1YoungRemSetSamplingThread::sleep_before_next_cycle() {
    46   MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
    49   MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
    47   if (!should_terminate()) {
    50   if (!should_terminate()) {
    48     uintx waitms = G1ConcRefinementServiceIntervalMillis; // 300, really should be?
    51     uintx waitms = G1ConcRefinementServiceIntervalMillis;
    49     _monitor.wait(Mutex::_no_safepoint_check_flag, waitms);
    52     _monitor.wait(Mutex::_no_safepoint_check_flag, waitms);
       
    53   }
       
    54 }
       
    55 
       
    56 bool G1YoungRemSetSamplingThread::should_start_periodic_gc() {
       
    57   // If we are currently in a concurrent mark we are going to uncommit memory soon.
       
    58   if (G1CollectedHeap::heap()->concurrent_mark()->cm_thread()->during_cycle()) {
       
    59     log_debug(gc, periodic)("Concurrent cycle in progress. Skipping.");
       
    60     return false;
       
    61   }
       
    62 
       
    63   // Check if enough time has passed since the last GC.
       
    64   uintx time_since_last_gc;
       
    65   if ((G1PeriodicGCInterval == 0) ||
       
    66       ((time_since_last_gc = (uintx)Universe::heap()->millis_since_last_gc()) < G1PeriodicGCInterval)) {
       
    67     log_debug(gc, periodic)("Last GC occurred " UINTX_FORMAT "ms before which is below threshold " UINTX_FORMAT "ms. Skipping.",
       
    68                             time_since_last_gc, G1PeriodicGCInterval);
       
    69     return false;
       
    70   }
       
    71 
       
    72   // Check if load is lower than max.
       
    73   double recent_load;
       
    74   if ((G1PeriodicGCSystemLoadThreshold > 0) &&
       
    75       (os::loadavg(&recent_load, 1) == -1 || recent_load > G1PeriodicGCSystemLoadThreshold)) {
       
    76     log_debug(gc, periodic)("Load %1.2f is higher than threshold " UINTX_FORMAT ". Skipping.",
       
    77                             recent_load, G1PeriodicGCSystemLoadThreshold);
       
    78     return false;
       
    79   }
       
    80 
       
    81   return true;
       
    82 }
       
    83 
       
    84 void G1YoungRemSetSamplingThread::check_for_periodic_gc(){
       
    85   if ((os::elapsedTime() - _last_periodic_gc_attempt_s) > (G1PeriodicGCInterval / 1000.0)) {
       
    86     log_debug(gc, periodic)("Checking for periodic GC.");
       
    87     if (should_start_periodic_gc()) {
       
    88       Universe::heap()->collect(GCCause::_g1_periodic_collection);
       
    89     }
       
    90     _last_periodic_gc_attempt_s = os::elapsedTime();
    50   }
    91   }
    51 }
    92 }
    52 
    93 
    53 void G1YoungRemSetSamplingThread::run_service() {
    94 void G1YoungRemSetSamplingThread::run_service() {
    54   double vtime_start = os::elapsedVTime();
    95   double vtime_start = os::elapsedVTime();
    59     if (os::supports_vtime()) {
   100     if (os::supports_vtime()) {
    60       _vtime_accum = (os::elapsedVTime() - vtime_start);
   101       _vtime_accum = (os::elapsedVTime() - vtime_start);
    61     } else {
   102     } else {
    62       _vtime_accum = 0.0;
   103       _vtime_accum = 0.0;
    63     }
   104     }
       
   105 
       
   106     check_for_periodic_gc();
    64 
   107 
    65     sleep_before_next_cycle();
   108     sleep_before_next_cycle();
    66   }
   109   }
    67 }
   110 }
    68 
   111