47
48 void G1YoungRemSetSamplingThread::sleep_before_next_cycle() {
49 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
50 if (!should_terminate()) {
51 uintx waitms = G1ConcRefinementServiceIntervalMillis;
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 earlier which is higher than 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::run_service() {
85 double vtime_start = os::elapsedVTime();
86
87 while (!should_terminate()) {
88 sample_young_list_rs_lengths();
89
90 if (os::supports_vtime()) {
91 _vtime_accum = (os::elapsedVTime() - vtime_start);
92 } else {
93 _vtime_accum = 0.0;
94 }
95
96 if ((os::elapsedTime() - _last_periodic_gc_attempt_s) > (G1PeriodicGCInterval / 1000.0)) {
97 log_debug(gc, periodic)("Checking for periodic GC.");
98 if (should_start_periodic_gc()) {
99 Universe::heap()->collect(GCCause::_g1_periodic_collection);
100 }
101 _last_periodic_gc_attempt_s = os::elapsedTime();
102 }
103
104 sleep_before_next_cycle();
105 }
106 }
107
108 void G1YoungRemSetSamplingThread::stop_service() {
109 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
110 _monitor.notify();
111 }
112
113 class G1YoungRemSetSamplingClosure : public HeapRegionClosure {
114 SuspendibleThreadSetJoiner* _sts;
115 size_t _regions_visited;
116 size_t _sampled_rs_lengths;
117 public:
118 G1YoungRemSetSamplingClosure(SuspendibleThreadSetJoiner* sts) :
119 HeapRegionClosure(), _sts(sts), _regions_visited(0), _sampled_rs_lengths(0) { }
120
121 virtual bool do_heap_region(HeapRegion* r) {
122 size_t rs_length = r->rem_set()->occupied();
|
47
48 void G1YoungRemSetSamplingThread::sleep_before_next_cycle() {
49 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
50 if (!should_terminate()) {
51 uintx waitms = G1ConcRefinementServiceIntervalMillis;
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();
91 }
92 }
93
94 void G1YoungRemSetSamplingThread::run_service() {
95 double vtime_start = os::elapsedVTime();
96
97 while (!should_terminate()) {
98 sample_young_list_rs_lengths();
99
100 if (os::supports_vtime()) {
101 _vtime_accum = (os::elapsedVTime() - vtime_start);
102 } else {
103 _vtime_accum = 0.0;
104 }
105
106 check_for_periodic_gc();
107
108 sleep_before_next_cycle();
109 }
110 }
111
112 void G1YoungRemSetSamplingThread::stop_service() {
113 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
114 _monitor.notify();
115 }
116
117 class G1YoungRemSetSamplingClosure : public HeapRegionClosure {
118 SuspendibleThreadSetJoiner* _sts;
119 size_t _regions_visited;
120 size_t _sampled_rs_lengths;
121 public:
122 G1YoungRemSetSamplingClosure(SuspendibleThreadSetJoiner* sts) :
123 HeapRegionClosure(), _sts(sts), _regions_visited(0), _sampled_rs_lengths(0) { }
124
125 virtual bool do_heap_region(HeapRegion* r) {
126 size_t rs_length = r->rem_set()->occupied();
|