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 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/g1/g1CollectedHeap.inline.hpp"
27 #include "gc/g1/g1CollectionSet.hpp"
28 #include "gc/g1/g1Policy.hpp"
29 #include "gc/g1/g1YoungRemSetSamplingThread.hpp"
30 #include "gc/g1/heapRegion.inline.hpp"
31 #include "gc/g1/heapRegionRemSet.hpp"
32 #include "gc/shared/suspendibleThreadSet.hpp"
33 #include "runtime/mutexLocker.hpp"
34
35 G1YoungRemSetSamplingThread::G1YoungRemSetSamplingThread() :
36 ConcurrentGCThread(),
37 _monitor(Mutex::nonleaf,
38 "G1YoungRemSetSamplingThread monitor",
39 true,
40 Monitor::_safepoint_check_never) {
41 set_name("G1 Young RemSet Sampling");
42 create_and_start();
43 }
44
45 void G1YoungRemSetSamplingThread::sleep_before_next_cycle() {
46 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
47 if (!should_terminate()) {
48 uintx waitms = G1ConcRefinementServiceIntervalMillis; // 300, really should be?
49 _monitor.wait(Mutex::_no_safepoint_check_flag, waitms);
50 }
51 }
52
53 void G1YoungRemSetSamplingThread::run_service() {
54 double vtime_start = os::elapsedVTime();
55
56 while (!should_terminate()) {
57 sample_young_list_rs_lengths();
58
59 if (os::supports_vtime()) {
60 _vtime_accum = (os::elapsedVTime() - vtime_start);
61 } else {
62 _vtime_accum = 0.0;
63 }
64
65 sleep_before_next_cycle();
66 }
67 }
68
69 void G1YoungRemSetSamplingThread::stop_service() {
70 MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
71 _monitor.notify();
72 }
73
74 class G1YoungRemSetSamplingClosure : public HeapRegionClosure {
75 SuspendibleThreadSetJoiner* _sts;
76 size_t _regions_visited;
77 size_t _sampled_rs_lengths;
78 public:
79 G1YoungRemSetSamplingClosure(SuspendibleThreadSetJoiner* sts) :
80 HeapRegionClosure(), _sts(sts), _regions_visited(0), _sampled_rs_lengths(0) { }
81
82 virtual bool do_heap_region(HeapRegion* r) {
83 size_t rs_length = r->rem_set()->occupied();
|
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 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/g1/g1CollectedHeap.inline.hpp"
27 #include "gc/g1/g1CollectionSet.hpp"
28 #include "gc/g1/g1ConcurrentMark.inline.hpp"
29 #include "gc/g1/g1ConcurrentMarkThread.inline.hpp"
30 #include "gc/g1/g1Policy.hpp"
31 #include "gc/g1/g1YoungRemSetSamplingThread.hpp"
32 #include "gc/g1/heapRegion.inline.hpp"
33 #include "gc/g1/heapRegionRemSet.hpp"
34 #include "gc/shared/suspendibleThreadSet.hpp"
35 #include "runtime/mutexLocker.hpp"
36
37 G1YoungRemSetSamplingThread::G1YoungRemSetSamplingThread() :
38 ConcurrentGCThread(),
39 _monitor(Mutex::nonleaf,
40 "G1YoungRemSetSamplingThread monitor",
41 true,
42 Monitor::_safepoint_check_never),
43 _last_periodic_gc_attempt_s(os::elapsedTime()) {
44 set_name("G1 Young RemSet Sampling");
45 create_and_start();
46 }
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();
|