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 */
23
24 #include "precompiled.hpp"
25 #include "gc/z/zCollectedHeap.hpp"
26 #include "gc/z/zCPU.inline.hpp"
27 #include "gc/z/zGlobals.hpp"
28 #include "gc/z/zHeap.inline.hpp"
29 #include "gc/z/zLargePages.inline.hpp"
30 #include "gc/z/zNMethodTable.hpp"
31 #include "gc/z/zNUMA.hpp"
32 #include "gc/z/zStat.hpp"
33 #include "gc/z/zTracer.inline.hpp"
34 #include "gc/z/zUtils.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "runtime/atomic.hpp"
37 #include "runtime/os.hpp"
38 #include "runtime/timer.hpp"
39 #include "utilities/align.hpp"
40 #include "utilities/compilerWarnings.hpp"
41 #include "utilities/debug.hpp"
42 #include "utilities/ticks.hpp"
43
44 #define ZSIZE_FMT SIZE_FORMAT "M(%.0f%%)"
45 #define ZSIZE_ARGS(size) ((size) / M), (percent_of(size, ZStatHeap::max_capacity()))
46
47 #define ZTABLE_ARGS_NA "%9s", "-"
48 #define ZTABLE_ARGS(size) SIZE_FORMAT_W(8) "M (%.0f%%)", \
49 ((size) / M), (percent_of(size, ZStatHeap::max_capacity()))
50
51 //
52 // Stat sampler/counter data
53 //
54 struct ZStatSamplerData {
55 uint64_t _nsamples;
56 uint64_t _sum;
57 uint64_t _max;
58
59 ZStatSamplerData() :
60 _nsamples(0),
61 _sum(0),
62 _max(0) {}
63
64 void add(const ZStatSamplerData& new_sample) {
65 _nsamples += new_sample._nsamples;
66 _sum += new_sample._sum;
67 _max = MAX2(_max, new_sample._max);
68 }
69 };
624 ZCollectedHeap::heap()->trace_heap_before_gc(ZTracer::tracer());
625
626 log_info(gc, start)("Garbage Collection (%s)",
627 GCCause::to_string(ZCollectedHeap::heap()->gc_cause()));
628 }
629
630 void ZStatPhaseCycle::register_end(const Ticks& start, const Ticks& end) const {
631 timer()->register_gc_end(end);
632
633 ZCollectedHeap::heap()->print_heap_after_gc();
634 ZCollectedHeap::heap()->trace_heap_after_gc(ZTracer::tracer());
635
636 ZTracer::tracer()->report_gc_end(end, timer()->time_partitions());
637
638 const Tickspan duration = end - start;
639 ZStatSample(_sampler, duration.value());
640
641 ZStatLoad::print();
642 ZStatMMU::print();
643 ZStatMark::print();
644 ZStatRelocation::print();
645 ZStatNMethods::print();
646 ZStatMetaspace::print();
647 ZStatReferences::print();
648 ZStatHeap::print();
649
650 log_info(gc)("Garbage Collection (%s) " ZSIZE_FMT "->" ZSIZE_FMT,
651 GCCause::to_string(ZCollectedHeap::heap()->gc_cause()),
652 ZSIZE_ARGS(ZStatHeap::used_at_mark_start()),
653 ZSIZE_ARGS(ZStatHeap::used_at_relocate_end()));
654 }
655
656 Tickspan ZStatPhasePause::_max;
657
658 ZStatPhasePause::ZStatPhasePause(const char* name) :
659 ZStatPhase("Phase", name) {}
660
661 const Tickspan& ZStatPhasePause::max() {
662 return _max;
663 }
664
665 void ZStatPhasePause::register_start(const Ticks& start) const {
666 timer()->register_gc_pause_start(name(), start);
667
1109 _ncontinue = ncontinue;
1110 }
1111
1112 void ZStatMark::print() {
1113 log_info(gc, marking)("Mark: "
1114 SIZE_FORMAT " stripe(s), "
1115 SIZE_FORMAT " proactive flush(es), "
1116 SIZE_FORMAT " terminate flush(es), "
1117 SIZE_FORMAT " completion(s), "
1118 SIZE_FORMAT " continuation(s) ",
1119 _nstripes,
1120 _nproactiveflush,
1121 _nterminateflush,
1122 _ntrycomplete,
1123 _ncontinue);
1124 }
1125
1126 //
1127 // Stat relocation
1128 //
1129 size_t ZStatRelocation::_relocating;
1130 bool ZStatRelocation::_success;
1131
1132 void ZStatRelocation::set_at_select_relocation_set(size_t relocating) {
1133 _relocating = relocating;
1134 }
1135
1136 void ZStatRelocation::set_at_relocate_end(bool success) {
1137 _success = success;
1138 }
1139
1140 void ZStatRelocation::print() {
1141 if (_success) {
1142 log_info(gc, reloc)("Relocation: Successful, " SIZE_FORMAT "M relocated", _relocating / M);
1143 } else {
1144 log_info(gc, reloc)("Relocation: Incomplete");
1145 }
1146 }
1147
1148 //
1149 // Stat nmethods
1150 //
1151 void ZStatNMethods::print() {
1152 log_info(gc, nmethod)("NMethods: " SIZE_FORMAT " registered, " SIZE_FORMAT " unregistered",
1153 ZNMethodTable::registered_nmethods(),
1154 ZNMethodTable::unregistered_nmethods());
1155 }
1156
1157 //
1158 // Stat metaspace
1159 //
1160 void ZStatMetaspace::print() {
1161 log_info(gc, metaspace)("Metaspace: "
1162 SIZE_FORMAT "M used, " SIZE_FORMAT "M capacity, "
1163 SIZE_FORMAT "M committed, " SIZE_FORMAT "M reserved",
1164 MetaspaceUtils::used_bytes() / M,
1165 MetaspaceUtils::capacity_bytes() / M,
1261 void ZStatHeap::set_at_mark_start(size_t soft_max_capacity,
1262 size_t capacity,
1263 size_t used) {
1264 _at_mark_start.soft_max_capacity = soft_max_capacity;
1265 _at_mark_start.capacity = capacity;
1266 _at_mark_start.reserve = reserve(used);
1267 _at_mark_start.used = used;
1268 _at_mark_start.free = free(used);
1269 }
1270
1271 void ZStatHeap::set_at_mark_end(size_t capacity,
1272 size_t allocated,
1273 size_t used) {
1274 _at_mark_end.capacity = capacity;
1275 _at_mark_end.reserve = reserve(used);
1276 _at_mark_end.allocated = allocated;
1277 _at_mark_end.used = used;
1278 _at_mark_end.free = free(used);
1279 }
1280
1281 void ZStatHeap::set_at_select_relocation_set(size_t live,
1282 size_t garbage,
1283 size_t reclaimed) {
1284 _at_mark_end.live = live;
1285 _at_mark_end.garbage = garbage;
1286
1287 _at_relocate_start.garbage = garbage - reclaimed;
1288 _at_relocate_start.reclaimed = reclaimed;
1289 }
1290
1291 void ZStatHeap::set_at_relocate_start(size_t capacity,
1292 size_t allocated,
1293 size_t used) {
1294 _at_relocate_start.capacity = capacity;
1295 _at_relocate_start.reserve = reserve(used);
1296 _at_relocate_start.allocated = allocated;
1297 _at_relocate_start.used = used;
1298 _at_relocate_start.free = free(used);
1299 }
1300
1301 void ZStatHeap::set_at_relocate_end(size_t capacity,
1302 size_t allocated,
1303 size_t reclaimed,
|
1 /*
2 * Copyright (c) 2015, 2020, 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 */
23
24 #include "precompiled.hpp"
25 #include "gc/z/zCollectedHeap.hpp"
26 #include "gc/z/zCPU.inline.hpp"
27 #include "gc/z/zGlobals.hpp"
28 #include "gc/z/zHeap.inline.hpp"
29 #include "gc/z/zLargePages.inline.hpp"
30 #include "gc/z/zNMethodTable.hpp"
31 #include "gc/z/zNUMA.hpp"
32 #include "gc/z/zRelocationSetSelector.inline.hpp"
33 #include "gc/z/zStat.hpp"
34 #include "gc/z/zTracer.inline.hpp"
35 #include "gc/z/zUtils.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "runtime/atomic.hpp"
38 #include "runtime/os.hpp"
39 #include "runtime/timer.hpp"
40 #include "utilities/align.hpp"
41 #include "utilities/compilerWarnings.hpp"
42 #include "utilities/debug.hpp"
43 #include "utilities/ticks.hpp"
44
45 #define ZSIZE_FMT SIZE_FORMAT "M(%.0f%%)"
46 #define ZSIZE_ARGS_WITH_MAX(size, max) ((size) / M), (percent_of(size, max))
47 #define ZSIZE_ARGS(size) ZSIZE_ARGS_WITH_MAX(size, ZStatHeap::max_capacity())
48
49 #define ZTABLE_ARGS_NA "%9s", "-"
50 #define ZTABLE_ARGS(size) SIZE_FORMAT_W(8) "M (%.0f%%)", \
51 ((size) / M), (percent_of(size, ZStatHeap::max_capacity()))
52
53 //
54 // Stat sampler/counter data
55 //
56 struct ZStatSamplerData {
57 uint64_t _nsamples;
58 uint64_t _sum;
59 uint64_t _max;
60
61 ZStatSamplerData() :
62 _nsamples(0),
63 _sum(0),
64 _max(0) {}
65
66 void add(const ZStatSamplerData& new_sample) {
67 _nsamples += new_sample._nsamples;
68 _sum += new_sample._sum;
69 _max = MAX2(_max, new_sample._max);
70 }
71 };
626 ZCollectedHeap::heap()->trace_heap_before_gc(ZTracer::tracer());
627
628 log_info(gc, start)("Garbage Collection (%s)",
629 GCCause::to_string(ZCollectedHeap::heap()->gc_cause()));
630 }
631
632 void ZStatPhaseCycle::register_end(const Ticks& start, const Ticks& end) const {
633 timer()->register_gc_end(end);
634
635 ZCollectedHeap::heap()->print_heap_after_gc();
636 ZCollectedHeap::heap()->trace_heap_after_gc(ZTracer::tracer());
637
638 ZTracer::tracer()->report_gc_end(end, timer()->time_partitions());
639
640 const Tickspan duration = end - start;
641 ZStatSample(_sampler, duration.value());
642
643 ZStatLoad::print();
644 ZStatMMU::print();
645 ZStatMark::print();
646 ZStatNMethods::print();
647 ZStatMetaspace::print();
648 ZStatReferences::print();
649 ZStatRelocation::print();
650 ZStatHeap::print();
651
652 log_info(gc)("Garbage Collection (%s) " ZSIZE_FMT "->" ZSIZE_FMT,
653 GCCause::to_string(ZCollectedHeap::heap()->gc_cause()),
654 ZSIZE_ARGS(ZStatHeap::used_at_mark_start()),
655 ZSIZE_ARGS(ZStatHeap::used_at_relocate_end()));
656 }
657
658 Tickspan ZStatPhasePause::_max;
659
660 ZStatPhasePause::ZStatPhasePause(const char* name) :
661 ZStatPhase("Phase", name) {}
662
663 const Tickspan& ZStatPhasePause::max() {
664 return _max;
665 }
666
667 void ZStatPhasePause::register_start(const Ticks& start) const {
668 timer()->register_gc_pause_start(name(), start);
669
1111 _ncontinue = ncontinue;
1112 }
1113
1114 void ZStatMark::print() {
1115 log_info(gc, marking)("Mark: "
1116 SIZE_FORMAT " stripe(s), "
1117 SIZE_FORMAT " proactive flush(es), "
1118 SIZE_FORMAT " terminate flush(es), "
1119 SIZE_FORMAT " completion(s), "
1120 SIZE_FORMAT " continuation(s) ",
1121 _nstripes,
1122 _nproactiveflush,
1123 _nterminateflush,
1124 _ntrycomplete,
1125 _ncontinue);
1126 }
1127
1128 //
1129 // Stat relocation
1130 //
1131 ZStatRelocation::Group ZStatRelocation::_small;
1132 ZStatRelocation::Group ZStatRelocation::_medium;
1133 ZStatRelocation::Group ZStatRelocation::_large;
1134 bool ZStatRelocation::_success;
1135
1136 void ZStatRelocation::set_at_select_relocation_set(const ZRelocationSetSelectorGroupStats& small,
1137 const ZRelocationSetSelectorGroupStats& medium,
1138 const ZRelocationSetSelectorGroupStats& large) {
1139 _small._npages = small.npages();
1140 _small._total = small.total();
1141 _small._empty = small.empty();
1142 _small._compacting_from = small.compacting_from();
1143 _small._compacting_to = small.compacting_to();
1144
1145 _medium._npages = medium.npages();
1146 _medium._total = medium.total();
1147 _medium._empty = medium.empty();
1148 _medium._compacting_from = medium.compacting_from();
1149 _medium._compacting_to = medium.compacting_to();
1150
1151 _large._npages = large.npages();
1152 _large._total = large.total();
1153 _large._empty = large.empty();
1154 _large._compacting_from = large.compacting_from();
1155 _large._compacting_to = large.compacting_to();
1156 }
1157
1158 void ZStatRelocation::set_at_relocate_end(bool success) {
1159 _success = success;
1160 }
1161
1162 void ZStatRelocation::print(const char* name, const ZStatRelocation::Group& group) {
1163 const size_t total = _small._total + _medium._total + _large._total;
1164
1165 log_info(gc, reloc)("%s Pages: " SIZE_FORMAT " / " ZSIZE_FMT ", Empty: " ZSIZE_FMT ", Compacting: " ZSIZE_FMT "->" ZSIZE_FMT,
1166 name,
1167 group._npages,
1168 ZSIZE_ARGS_WITH_MAX(group._total, total),
1169 ZSIZE_ARGS_WITH_MAX(group._empty, total),
1170 ZSIZE_ARGS_WITH_MAX(group._compacting_from, total),
1171 ZSIZE_ARGS_WITH_MAX(group._compacting_to, total));
1172 }
1173
1174 void ZStatRelocation::print() {
1175 print("Small", _small);
1176 print("Medium", _medium);
1177 print("Large", _large);
1178
1179 log_info(gc, reloc)("Relocation: %s", _success ? "Successful" : "Incomplete");
1180 }
1181
1182 //
1183 // Stat nmethods
1184 //
1185 void ZStatNMethods::print() {
1186 log_info(gc, nmethod)("NMethods: " SIZE_FORMAT " registered, " SIZE_FORMAT " unregistered",
1187 ZNMethodTable::registered_nmethods(),
1188 ZNMethodTable::unregistered_nmethods());
1189 }
1190
1191 //
1192 // Stat metaspace
1193 //
1194 void ZStatMetaspace::print() {
1195 log_info(gc, metaspace)("Metaspace: "
1196 SIZE_FORMAT "M used, " SIZE_FORMAT "M capacity, "
1197 SIZE_FORMAT "M committed, " SIZE_FORMAT "M reserved",
1198 MetaspaceUtils::used_bytes() / M,
1199 MetaspaceUtils::capacity_bytes() / M,
1295 void ZStatHeap::set_at_mark_start(size_t soft_max_capacity,
1296 size_t capacity,
1297 size_t used) {
1298 _at_mark_start.soft_max_capacity = soft_max_capacity;
1299 _at_mark_start.capacity = capacity;
1300 _at_mark_start.reserve = reserve(used);
1301 _at_mark_start.used = used;
1302 _at_mark_start.free = free(used);
1303 }
1304
1305 void ZStatHeap::set_at_mark_end(size_t capacity,
1306 size_t allocated,
1307 size_t used) {
1308 _at_mark_end.capacity = capacity;
1309 _at_mark_end.reserve = reserve(used);
1310 _at_mark_end.allocated = allocated;
1311 _at_mark_end.used = used;
1312 _at_mark_end.free = free(used);
1313 }
1314
1315 void ZStatHeap::set_at_select_relocation_set(const ZRelocationSetSelectorGroupStats& small,
1316 const ZRelocationSetSelectorGroupStats& medium,
1317 const ZRelocationSetSelectorGroupStats& large,
1318 size_t reclaimed) {
1319 const size_t live = small.live() + medium.live() + large.live();
1320 const size_t garbage = small.garbage() + medium.garbage() + large.garbage();
1321
1322 _at_mark_end.live = live;
1323 _at_mark_end.garbage = garbage;
1324
1325 _at_relocate_start.garbage = garbage - reclaimed;
1326 _at_relocate_start.reclaimed = reclaimed;
1327 }
1328
1329 void ZStatHeap::set_at_relocate_start(size_t capacity,
1330 size_t allocated,
1331 size_t used) {
1332 _at_relocate_start.capacity = capacity;
1333 _at_relocate_start.reserve = reserve(used);
1334 _at_relocate_start.allocated = allocated;
1335 _at_relocate_start.used = used;
1336 _at_relocate_start.free = free(used);
1337 }
1338
1339 void ZStatHeap::set_at_relocate_end(size_t capacity,
1340 size_t allocated,
1341 size_t reclaimed,
|