1 /*
2 * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
45 set_name("G1 Young RemSet Sampling");
46 create_and_start();
47 }
48
49 void G1YoungRemSetSamplingThread::sleep_before_next_cycle() {
50 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
51 if (!should_terminate()) {
52 uintx waitms = G1ConcRefinementServiceIntervalMillis;
53 _monitor.wait(Mutex::_no_safepoint_check_flag, waitms);
54 }
55 }
56
57 bool G1YoungRemSetSamplingThread::should_start_periodic_gc() {
58 // If we are currently in a concurrent mark we are going to uncommit memory soon.
59 if (G1CollectedHeap::heap()->concurrent_mark()->cm_thread()->during_cycle()) {
60 log_debug(gc, periodic)("Concurrent cycle in progress. Skipping.");
61 return false;
62 }
63
64 // Check if enough time has passed since the last GC.
65 uintx time_since_last_gc;
66 if ((G1PeriodicGCInterval == 0) ||
67 ((time_since_last_gc = (uintx)Universe::heap()->millis_since_last_gc()) < G1PeriodicGCInterval)) {
68 log_debug(gc, periodic)("Last GC occurred " UINTX_FORMAT "ms before which is below threshold " UINTX_FORMAT "ms. Skipping.",
69 time_since_last_gc, G1PeriodicGCInterval);
70 return false;
71 }
72
73 // Check if load is lower than max.
74 double recent_load;
75 if ((G1PeriodicGCSystemLoadThreshold > 0.0f) &&
76 (os::loadavg(&recent_load, 1) == -1 || recent_load > G1PeriodicGCSystemLoadThreshold)) {
77 log_debug(gc, periodic)("Load %1.2f is higher than threshold %1.2f. Skipping.",
78 recent_load, G1PeriodicGCSystemLoadThreshold);
79 return false;
80 }
81
82 return true;
83 }
84
85 void G1YoungRemSetSamplingThread::check_for_periodic_gc(){
86 if ((os::elapsedTime() - _last_periodic_gc_attempt_s) > (G1PeriodicGCInterval / 1000.0)) {
87 log_debug(gc, periodic)("Checking for periodic GC.");
88 if (should_start_periodic_gc()) {
89 Universe::heap()->collect(GCCause::_g1_periodic_collection);
90 }
91 _last_periodic_gc_attempt_s = os::elapsedTime();
92 }
93 }
94
95 void G1YoungRemSetSamplingThread::run_service() {
96 double vtime_start = os::elapsedVTime();
97
98 while (!should_terminate()) {
99 sample_young_list_rs_lengths();
100
101 if (os::supports_vtime()) {
102 _vtime_accum = (os::elapsedVTime() - vtime_start);
103 } else {
104 _vtime_accum = 0.0;
105 }
106
107 check_for_periodic_gc();
108
109 sleep_before_next_cycle();
110 }
111 }
112
113 void G1YoungRemSetSamplingThread::stop_service() {
114 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
115 _monitor.notify();
116 }
|
1 /*
2 * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
45 set_name("G1 Young RemSet Sampling");
46 create_and_start();
47 }
48
49 void G1YoungRemSetSamplingThread::sleep_before_next_cycle() {
50 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
51 if (!should_terminate()) {
52 uintx waitms = G1ConcRefinementServiceIntervalMillis;
53 _monitor.wait(Mutex::_no_safepoint_check_flag, waitms);
54 }
55 }
56
57 bool G1YoungRemSetSamplingThread::should_start_periodic_gc() {
58 // If we are currently in a concurrent mark we are going to uncommit memory soon.
59 if (G1CollectedHeap::heap()->concurrent_mark()->cm_thread()->during_cycle()) {
60 log_debug(gc, periodic)("Concurrent cycle in progress. Skipping.");
61 return false;
62 }
63
64 // Check if enough time has passed since the last GC.
65 uintx time_since_last_gc = (uintx)Universe::heap()->millis_since_last_gc();
66 if ((time_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.0f) &&
75 (os::loadavg(&recent_load, 1) == -1 || recent_load > G1PeriodicGCSystemLoadThreshold)) {
76 log_debug(gc, periodic)("Load %1.2f is higher than threshold %1.2f. Skipping.",
77 recent_load, G1PeriodicGCSystemLoadThreshold);
78 return false;
79 }
80
81 return true;
82 }
83
84 void G1YoungRemSetSamplingThread::check_for_periodic_gc(){
85 // If disabled, just return.
86 if (G1PeriodicGCInterval == 0) {
87 return;
88 }
89 if ((os::elapsedTime() - _last_periodic_gc_attempt_s) > (G1PeriodicGCInterval / 1000.0)) {
90 log_debug(gc, periodic)("Checking for periodic GC.");
91 if (should_start_periodic_gc()) {
92 Universe::heap()->collect(GCCause::_g1_periodic_collection);
93 }
94 _last_periodic_gc_attempt_s = os::elapsedTime();
95 }
96 }
97
98 void G1YoungRemSetSamplingThread::run_service() {
99 double vtime_start = os::elapsedVTime();
100
101 // Print a message about periodic GC configuration.
102 if (G1PeriodicGCInterval != 0) {
103 log_info(gc)("Periodic GC enabled with interval " UINTX_FORMAT "ms", G1PeriodicGCInterval);
104 } else {
105 log_info(gc)("Periodic GC disabled");
106 }
107
108 while (!should_terminate()) {
109 sample_young_list_rs_lengths();
110
111 if (os::supports_vtime()) {
112 _vtime_accum = (os::elapsedVTime() - vtime_start);
113 } else {
114 _vtime_accum = 0.0;
115 }
116
117 check_for_periodic_gc();
118
119 sleep_before_next_cycle();
120 }
121 }
122
123 void G1YoungRemSetSamplingThread::stop_service() {
124 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
125 _monitor.notify();
126 }
|