Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/memory/metaspace/metaspaceReporter.cpp
40957 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
//////////// Waste section ///////////////////////////
304
// As a convenience, print a summary of common waste.
305
out->cr();
306
out->print("Waste (unused committed space):");
307
// For all wastages, print percentages from total. As total use the total size of memory committed for metaspace.
308
const size_t committed_words = RunningCounters::committed_words();
309
310
out->print("(percentages refer to total committed size ");
311
print_scaled_words(out, committed_words, scale);
312
out->print_cr("):");
313
314
// Print waste for in-use chunks.
315
InUseChunkStats ucs_nonclass = cl._stats_total._arena_stats_nonclass.totals();
316
InUseChunkStats ucs_class = cl._stats_total._arena_stats_class.totals();
317
const size_t waste_in_chunks_in_use = ucs_nonclass._waste_words + ucs_class._waste_words;
318
const size_t free_in_chunks_in_use = ucs_nonclass._free_words + ucs_class._free_words;
319
320
out->print(" Waste in chunks in use: ");
321
print_scaled_words_and_percentage(out, waste_in_chunks_in_use, committed_words, scale, 6);
322
out->cr();
323
out->print(" Free in chunks in use: ");
324
print_scaled_words_and_percentage(out, free_in_chunks_in_use, committed_words, scale, 6);
325
out->cr();
326
327
// Print waste in free chunks.
328
const size_t committed_in_free_chunks = total_cm_stat.total_committed_word_size();
329
out->print(" In free chunks: ");
330
print_scaled_words_and_percentage(out, committed_in_free_chunks, committed_words, scale, 6);
331
out->cr();
332
333
// Print waste in deallocated blocks.
334
const uintx free_blocks_num =
335
cl._stats_total._arena_stats_nonclass._free_blocks_num +
336
cl._stats_total._arena_stats_class._free_blocks_num;
337
const size_t free_blocks_cap_words =
338
cl._stats_total._arena_stats_nonclass._free_blocks_word_size +
339
cl._stats_total._arena_stats_class._free_blocks_word_size;
340
out->print("Deallocated from chunks in use: ");
341
print_scaled_words_and_percentage(out, free_blocks_cap_words, committed_words, scale, 6);
342
out->print(" (" UINTX_FORMAT " blocks)", free_blocks_num);
343
out->cr();
344
345
// Print total waste.
346
const size_t total_waste =
347
waste_in_chunks_in_use +
348
free_in_chunks_in_use +
349
committed_in_free_chunks +
350
free_blocks_cap_words;
351
out->print(" -total-: ");
352
print_scaled_words_and_percentage(out, total_waste, committed_words, scale, 6);
353
out->cr();
354
355
// Also print chunk header pool size.
356
out->cr();
357
out->print("chunk header pool: %u items, ", ChunkHeaderPool::pool()->used());
358
print_scaled_words(out, ChunkHeaderPool::pool()->memory_footprint_words(), scale);
359
out->print(".");
360
out->cr();
361
362
// Print internal statistics
363
out->cr();
364
out->print_cr("Internal statistics:");
365
out->cr();
366
InternalStats::print_on(out);
367
out->cr();
368
369
// Print some interesting settings
370
out->cr();
371
out->print_cr("Settings:");
372
print_settings(out, scale);
373
374
out->cr();
375
out->cr();
376
377
DEBUG_ONLY(MetaspaceUtils::verify();)
378
} // MetaspaceUtils::print_report()
379
380
} // namespace metaspace
381
382
383