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