Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/hotspot/share/memory/metaspace/metaspaceReporter.cpp
66644 views
1
/*
2
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
3
* Copyright (c) 2018, 2020 SAP SE. All rights reserved.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*
24
*/
25
26
#include "precompiled.hpp"
27
#include "classfile/classLoaderData.hpp"
28
#include "classfile/classLoaderDataGraph.hpp"
29
#include "memory/metaspace.hpp"
30
#include "memory/metaspace/chunkHeaderPool.hpp"
31
#include "memory/metaspace/chunkManager.hpp"
32
#include "memory/metaspace/internalStats.hpp"
33
#include "memory/metaspace/metaspaceCommon.hpp"
34
#include "memory/metaspace/metaspaceReporter.hpp"
35
#include "memory/metaspace/metaspaceSettings.hpp"
36
#include "memory/metaspace/metaspaceStatistics.hpp"
37
#include "memory/metaspace/printCLDMetaspaceInfoClosure.hpp"
38
#include "memory/metaspace/runningCounters.hpp"
39
#include "memory/metaspace/virtualSpaceList.hpp"
40
#include "memory/metaspaceUtils.hpp"
41
#include "runtime/os.hpp"
42
43
namespace metaspace {
44
45
static const char* describe_spacetype(Metaspace::MetaspaceType st) {
46
const char* s = NULL;
47
switch (st) {
48
case Metaspace::StandardMetaspaceType: s = "Standard"; break;
49
case Metaspace::BootMetaspaceType: s = "Boot"; break;
50
case Metaspace::ClassMirrorHolderMetaspaceType: s = "ClassMirrorHolder"; break;
51
case Metaspace::ReflectionMetaspaceType: s = "Reflection"; break;
52
default: ShouldNotReachHere();
53
}
54
return s;
55
}
56
57
static void print_vs(outputStream* out, size_t scale) {
58
const size_t reserved_nc = RunningCounters::reserved_words_nonclass();
59
const size_t committed_nc = RunningCounters::committed_words_nonclass();
60
const int num_nodes_nc = VirtualSpaceList::vslist_nonclass()->num_nodes();
61
62
if (Metaspace::using_class_space()) {
63
const size_t reserved_c = RunningCounters::reserved_words_class();
64
const size_t committed_c = RunningCounters::committed_words_class();
65
const int num_nodes_c = VirtualSpaceList::vslist_class()->num_nodes();
66
67
out->print(" Non-class space: ");
68
print_scaled_words(out, reserved_nc, scale, 7);
69
out->print(" reserved, ");
70
print_scaled_words_and_percentage(out, committed_nc, reserved_nc, scale, 7);
71
out->print(" committed, ");
72
out->print(" %d nodes.", num_nodes_nc);
73
out->cr();
74
out->print(" Class space: ");
75
print_scaled_words(out, reserved_c, scale, 7);
76
out->print(" reserved, ");
77
print_scaled_words_and_percentage(out, committed_c, reserved_c, scale, 7);
78
out->print(" committed, ");
79
out->print(" %d nodes.", num_nodes_c);
80
out->cr();
81
out->print(" Both: ");
82
print_scaled_words(out, reserved_c + reserved_nc, scale, 7);
83
out->print(" reserved, ");
84
print_scaled_words_and_percentage(out, committed_c + committed_nc, reserved_c + reserved_nc, scale, 7);
85
out->print(" committed. ");
86
out->cr();
87
} else {
88
print_scaled_words(out, reserved_nc, scale, 7);
89
out->print(" reserved, ");
90
print_scaled_words_and_percentage(out, committed_nc, reserved_nc, scale, 7);
91
out->print(" committed, ");
92
out->print(" %d nodes.", num_nodes_nc);
93
out->cr();
94
}
95
}
96
97
static void print_settings(outputStream* out, size_t scale) {
98
out->print("MaxMetaspaceSize: ");
99
if (MaxMetaspaceSize == max_uintx) {
100
out->print("unlimited");
101
} else {
102
print_human_readable_size(out, MaxMetaspaceSize, scale);
103
}
104
out->cr();
105
if (Metaspace::using_class_space()) {
106
out->print("CompressedClassSpaceSize: ");
107
print_human_readable_size(out, CompressedClassSpaceSize, scale);
108
} else {
109
out->print("No class space");
110
}
111
out->cr();
112
out->print("Initial GC threshold: ");
113
print_human_readable_size(out, MetaspaceSize, scale);
114
out->cr();
115
out->print("Current GC threshold: ");
116
print_human_readable_size(out, MetaspaceGC::capacity_until_GC(), scale);
117
out->cr();
118
out->print_cr("CDS: %s", (UseSharedSpaces ? "on" : (DumpSharedSpaces ? "dump" : "off")));
119
out->print_cr("MetaspaceReclaimPolicy: %s", MetaspaceReclaimPolicy);
120
Settings::print_on(out);
121
}
122
123
// This will print out a basic metaspace usage report but
124
// unlike print_report() is guaranteed not to lock or to walk the CLDG.
125
void MetaspaceReporter::print_basic_report(outputStream* out, size_t scale) {
126
if (!Metaspace::initialized()) {
127
out->print_cr("Metaspace not yet initialized.");
128
return;
129
}
130
out->cr();
131
out->print_cr("Usage:");
132
if (Metaspace::using_class_space()) {
133
out->print(" Non-class: ");
134
}
135
136
// Note: since we want to purely rely on counters, without any locking or walking the CLDG,
137
// for Usage stats (statistics over in-use chunks) all we can print is the
138
// used words. We cannot print committed areas, or free/waste areas, of in-use chunks require
139
// walking.
140
const size_t used_nc = MetaspaceUtils::used_words(Metaspace::NonClassType);
141
142
print_scaled_words(out, used_nc, scale, 5);
143
out->print(" used.");
144
out->cr();
145
if (Metaspace::using_class_space()) {
146
const size_t used_c = MetaspaceUtils::used_words(Metaspace::ClassType);
147
out->print(" Class: ");
148
print_scaled_words(out, used_c, scale, 5);
149
out->print(" used.");
150
out->cr();
151
out->print(" Both: ");
152
const size_t used = used_nc + used_c;
153
print_scaled_words(out, used, scale, 5);
154
out->print(" used.");
155
out->cr();
156
}
157
out->cr();
158
out->print_cr("Virtual space:");
159
print_vs(out, scale);
160
out->cr();
161
out->print_cr("Chunk freelists:");
162
if (Metaspace::using_class_space()) {
163
out->print(" Non-Class: ");
164
}
165
print_scaled_words(out, ChunkManager::chunkmanager_nonclass()->total_word_size(), scale);
166
out->cr();
167
if (Metaspace::using_class_space()) {
168
out->print(" Class: ");
169
print_scaled_words(out, ChunkManager::chunkmanager_class()->total_word_size(), scale);
170
out->cr();
171
out->print(" Both: ");
172
print_scaled_words(out, ChunkManager::chunkmanager_nonclass()->total_word_size() +
173
ChunkManager::chunkmanager_class()->total_word_size(), scale);
174
out->cr();
175
}
176
out->cr();
177
178
// Print basic settings
179
print_settings(out, scale);
180
out->cr();
181
out->cr();
182
out->print_cr("Internal statistics:");
183
out->cr();
184
InternalStats::print_on(out);
185
out->cr();
186
}
187
188
void MetaspaceReporter::print_report(outputStream* out, size_t scale, int flags) {
189
if (!Metaspace::initialized()) {
190
out->print_cr("Metaspace not yet initialized.");
191
return;
192
}
193
const bool print_loaders = (flags & (int)Option::ShowLoaders) > 0;
194
const bool print_classes = (flags & (int)Option::ShowClasses) > 0;
195
const bool print_by_chunktype = (flags & (int)Option::BreakDownByChunkType) > 0;
196
const bool print_by_spacetype = (flags & (int)Option::BreakDownBySpaceType) > 0;
197
198
// Some report options require walking the class loader data graph.
199
metaspace::PrintCLDMetaspaceInfoClosure cl(out, scale, print_loaders, print_classes, print_by_chunktype);
200
if (print_loaders) {
201
out->cr();
202
out->print_cr("Usage per loader:");
203
out->cr();
204
}
205
206
ClassLoaderDataGraph::loaded_cld_do(&cl); // collect data and optionally print
207
208
// Print totals, broken up by space type.
209
if (print_by_spacetype) {
210
out->cr();
211
out->print_cr("Usage per space type:");
212
out->cr();
213
for (int space_type = (int)Metaspace::ZeroMetaspaceType;
214
space_type < (int)Metaspace::MetaspaceTypeCount; space_type++)
215
{
216
uintx num_loaders = cl._num_loaders_by_spacetype[space_type];
217
uintx num_classes = cl._num_classes_by_spacetype[space_type];
218
out->print("%s - " UINTX_FORMAT " %s",
219
describe_spacetype((Metaspace::MetaspaceType)space_type),
220
num_loaders, loaders_plural(num_loaders));
221
if (num_classes > 0) {
222
out->print(", ");
223
224
print_number_of_classes(out, num_classes, cl._num_classes_shared_by_spacetype[space_type]);
225
out->print(":");
226
cl._stats_by_spacetype[space_type].print_on(out, scale, print_by_chunktype);
227
} else {
228
out->print(".");
229
out->cr();
230
}
231
out->cr();
232
}
233
}
234
235
// Print totals for in-use data:
236
out->cr();
237
{
238
uintx num_loaders = cl._num_loaders;
239
out->print("Total Usage - " UINTX_FORMAT " %s, ",
240
num_loaders, loaders_plural(num_loaders));
241
print_number_of_classes(out, cl._num_classes, cl._num_classes_shared);
242
out->print(":");
243
cl._stats_total.print_on(out, scale, print_by_chunktype);
244
out->cr();
245
}
246
247
/////////////////////////////////////////////////
248
// -- Print Virtual space.
249
out->cr();
250
out->print_cr("Virtual space:");
251
252
print_vs(out, scale);
253
254
// -- Print VirtualSpaceList details.
255
if ((flags & (int)Option::ShowVSList) > 0) {
256
out->cr();
257
out->print_cr("Virtual space list%s:", Metaspace::using_class_space() ? "s" : "");
258
259
if (Metaspace::using_class_space()) {
260
out->print_cr(" Non-Class:");
261
}
262
VirtualSpaceList::vslist_nonclass()->print_on(out);
263
out->cr();
264
if (Metaspace::using_class_space()) {
265
out->print_cr(" Class:");
266
VirtualSpaceList::vslist_class()->print_on(out);
267
out->cr();
268
}
269
}
270
out->cr();
271
272
//////////// Freelists (ChunkManager) section ///////////////////////////
273
274
out->cr();
275
out->print_cr("Chunk freelist%s:", Metaspace::using_class_space() ? "s" : "");
276
277
ChunkManagerStats non_class_cm_stat;
278
ChunkManagerStats class_cm_stat;
279
ChunkManagerStats total_cm_stat;
280
281
ChunkManager::chunkmanager_nonclass()->add_to_statistics(&non_class_cm_stat);
282
if (Metaspace::using_class_space()) {
283
ChunkManager::chunkmanager_nonclass()->add_to_statistics(&non_class_cm_stat);
284
ChunkManager::chunkmanager_class()->add_to_statistics(&class_cm_stat);
285
total_cm_stat.add(non_class_cm_stat);
286
total_cm_stat.add(class_cm_stat);
287
288
out->print_cr(" Non-Class:");
289
non_class_cm_stat.print_on(out, scale);
290
out->cr();
291
out->print_cr(" Class:");
292
class_cm_stat.print_on(out, scale);
293
out->cr();
294
out->print_cr(" Both:");
295
total_cm_stat.print_on(out, scale);
296
out->cr();
297
} else {
298
ChunkManager::chunkmanager_nonclass()->add_to_statistics(&non_class_cm_stat);
299
non_class_cm_stat.print_on(out, scale);
300
out->cr();
301
}
302
303
// -- Print Chunkmanager details.
304
if ((flags & (int)Option::ShowChunkFreeList) > 0) {
305
out->cr();
306
out->print_cr("Chunk freelist details:");
307
if (Metaspace::using_class_space()) {
308
out->print_cr(" Non-Class:");
309
}
310
ChunkManager::chunkmanager_nonclass()->print_on(out);
311
out->cr();
312
if (Metaspace::using_class_space()) {
313
out->print_cr(" Class:");
314
ChunkManager::chunkmanager_class()->print_on(out);
315
out->cr();
316
}
317
}
318
out->cr();
319
320
321
//////////// Waste section ///////////////////////////
322
// As a convenience, print a summary of common waste.
323
out->cr();
324
out->print("Waste (unused committed space):");
325
// For all wastages, print percentages from total. As total use the total size of memory committed for metaspace.
326
const size_t committed_words = RunningCounters::committed_words();
327
328
out->print("(percentages refer to total committed size ");
329
print_scaled_words(out, committed_words, scale);
330
out->print_cr("):");
331
332
// Print waste for in-use chunks.
333
InUseChunkStats ucs_nonclass = cl._stats_total._arena_stats_nonclass.totals();
334
InUseChunkStats ucs_class = cl._stats_total._arena_stats_class.totals();
335
const size_t waste_in_chunks_in_use = ucs_nonclass._waste_words + ucs_class._waste_words;
336
const size_t free_in_chunks_in_use = ucs_nonclass._free_words + ucs_class._free_words;
337
338
out->print(" Waste in chunks in use: ");
339
print_scaled_words_and_percentage(out, waste_in_chunks_in_use, committed_words, scale, 6);
340
out->cr();
341
out->print(" Free in chunks in use: ");
342
print_scaled_words_and_percentage(out, free_in_chunks_in_use, committed_words, scale, 6);
343
out->cr();
344
345
// Print waste in free chunks.
346
const size_t committed_in_free_chunks = total_cm_stat.total_committed_word_size();
347
out->print(" In free chunks: ");
348
print_scaled_words_and_percentage(out, committed_in_free_chunks, committed_words, scale, 6);
349
out->cr();
350
351
// Print waste in deallocated blocks.
352
const uintx free_blocks_num =
353
cl._stats_total._arena_stats_nonclass._free_blocks_num +
354
cl._stats_total._arena_stats_class._free_blocks_num;
355
const size_t free_blocks_cap_words =
356
cl._stats_total._arena_stats_nonclass._free_blocks_word_size +
357
cl._stats_total._arena_stats_class._free_blocks_word_size;
358
out->print("Deallocated from chunks in use: ");
359
print_scaled_words_and_percentage(out, free_blocks_cap_words, committed_words, scale, 6);
360
out->print(" (" UINTX_FORMAT " blocks)", free_blocks_num);
361
out->cr();
362
363
// Print total waste.
364
const size_t total_waste =
365
waste_in_chunks_in_use +
366
free_in_chunks_in_use +
367
committed_in_free_chunks +
368
free_blocks_cap_words;
369
out->print(" -total-: ");
370
print_scaled_words_and_percentage(out, total_waste, committed_words, scale, 6);
371
out->cr();
372
373
// Also print chunk header pool size.
374
out->cr();
375
out->print("chunk header pool: %u items, ", ChunkHeaderPool::pool()->used());
376
print_scaled_words(out, ChunkHeaderPool::pool()->memory_footprint_words(), scale);
377
out->print(".");
378
out->cr();
379
380
// Print internal statistics
381
out->cr();
382
out->print_cr("Internal statistics:");
383
out->cr();
384
InternalStats::print_on(out);
385
out->cr();
386
387
// Print some interesting settings
388
out->cr();
389
out->print_cr("Settings:");
390
print_settings(out, scale);
391
392
out->cr();
393
out->cr();
394
395
DEBUG_ONLY(MetaspaceUtils::verify();)
396
} // MetaspaceUtils::print_report()
397
398
} // namespace metaspace
399
400
401