1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2018, SAP and/or its affiliates. 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 #include "precompiled.hpp" 26 #include "memory/metaspace/metaspaceCommon.hpp" 27 #include "memory/metaspace/metaspaceDCmd.hpp" 28 #include "memory/resourceArea.hpp" 29 #include "services/diagnosticCommand.hpp" 30 #include "services/nmtCommon.hpp" 31 32 namespace metaspace { 33 34 static const char* space_type_name(Metaspace::MetaspaceType t) { 35 const char* s = NULL; 36 switch (t) { 37 case Metaspace::StandardMetaspaceType: s = "Standard"; break; 38 case Metaspace::BootMetaspaceType: s = "Boot"; break; 39 case Metaspace::UnsafeAnonymousMetaspaceType: s = "UnsafeAnonymous"; break; 40 case Metaspace::ReflectionMetaspaceType: s = "Reflection"; break; 41 default: ShouldNotReachHere(); 42 } 43 return s; 44 } 45 46 static void print_vs(outputStream* out, size_t scale) { 47 const size_t reserved_nonclass_words = reserved_bytes(Metaspace::NonClassType) / sizeof(MetaWord); 48 const size_t committed_nonclass_words = committed_bytes(Metaspace::NonClassType) / sizeof(MetaWord); 49 { 50 if (Metaspace::using_class_space()) { 51 out->print(" Non-class space: "); 52 } 53 print_scaled_words(out, reserved_nonclass_words, scale, 7); 54 out->print(" reserved, "); 55 print_scaled_words_and_percentage(out, committed_nonclass_words, reserved_nonclass_words, scale, 7); 56 out->print_cr(" committed "); 57 58 if (Metaspace::using_class_space()) { 59 const size_t reserved_class_words = reserved_bytes(Metaspace::ClassType) / sizeof(MetaWord); 60 const size_t committed_class_words = committed_bytes(Metaspace::ClassType) / sizeof(MetaWord); 61 out->print(" Class space: "); 62 print_scaled_words(out, reserved_class_words, scale, 7); 63 out->print(" reserved, "); 64 print_scaled_words_and_percentage(out, committed_class_words, reserved_class_words, scale, 7); 65 out->print_cr(" committed "); 66 67 const size_t reserved_words = reserved_nonclass_words + reserved_class_words; 68 const size_t committed_words = committed_nonclass_words + committed_class_words; 69 out->print(" Both: "); 70 print_scaled_words(out, reserved_words, scale, 7); 71 out->print(" reserved, "); 72 print_scaled_words_and_percentage(out, committed_words, reserved_words, scale, 7); 73 out->print_cr(" committed "); 74 } 75 } 76 } 77 78 static void print_basic_switches(outputStream* out, size_t scale) { 79 out->print("MaxMetaspaceSize: "); 80 if (MaxMetaspaceSize >= (max_uintx) - (2 * os::vm_page_size())) { 81 // aka "very big". Default is max_uintx, but due to rounding in arg parsing the real 82 // value is smaller. 83 out->print("unlimited"); 84 } else { 85 print_human_readable_size(out, MaxMetaspaceSize, scale); 86 } 87 out->cr(); 88 if (Metaspace::using_class_space()) { 89 out->print("CompressedClassSpaceSize: "); 90 print_human_readable_size(out, CompressedClassSpaceSize, scale); 91 } 92 out->cr(); 93 } 94 95 // This will print out a basic metaspace usage report but 96 // unlike print_report() is guaranteed not to lock or to walk the CLDG. 97 void MetaspaceUtils::print_basic_report(outputStream* out, size_t scale) { 98 99 if (!Metaspace::initialized()) { 100 out->print_cr("Metaspace not yet initialized."); 101 return; 102 } 103 104 out->cr(); 105 out->print_cr("Usage:"); 106 107 if (Metaspace::using_class_space()) { 108 out->print(" Non-class: "); 109 } 110 111 // In its most basic form, we do not require walking the CLDG. Instead, just print the running totals from 112 // MetaspaceUtils. 113 const size_t cap_nc = MetaspaceUtils::capacity_words(Metaspace::NonClassType); 114 const size_t overhead_nc = MetaspaceUtils::overhead_words(Metaspace::NonClassType); 115 const size_t used_nc = MetaspaceUtils::used_words(Metaspace::NonClassType); 116 const size_t free_and_waste_nc = cap_nc - overhead_nc - used_nc; 117 118 print_scaled_words(out, cap_nc, scale, 5); 119 out->print(" capacity, "); 120 print_scaled_words_and_percentage(out, used_nc, cap_nc, scale, 5); 121 out->print(" used, "); 122 print_scaled_words_and_percentage(out, free_and_waste_nc, cap_nc, scale, 5); 123 out->print(" free+waste, "); 124 print_scaled_words_and_percentage(out, overhead_nc, cap_nc, scale, 5); 125 out->print(" overhead. "); 126 out->cr(); 127 128 if (Metaspace::using_class_space()) { 129 const size_t cap_c = MetaspaceUtils::capacity_words(Metaspace::ClassType); 130 const size_t overhead_c = MetaspaceUtils::overhead_words(Metaspace::ClassType); 131 const size_t used_c = MetaspaceUtils::used_words(Metaspace::ClassType); 132 const size_t free_and_waste_c = cap_c - overhead_c - used_c; 133 out->print(" Class: "); 134 print_scaled_words(out, cap_c, scale, 5); 135 out->print(" capacity, "); 136 print_scaled_words_and_percentage(out, used_c, cap_c, scale, 5); 137 out->print(" used, "); 138 print_scaled_words_and_percentage(out, free_and_waste_c, cap_c, scale, 5); 139 out->print(" free+waste, "); 140 print_scaled_words_and_percentage(out, overhead_c, cap_c, scale, 5); 141 out->print(" overhead. "); 142 out->cr(); 143 144 out->print(" Both: "); 145 const size_t cap = cap_nc + cap_c; 146 147 print_scaled_words(out, cap, scale, 5); 148 out->print(" capacity, "); 149 print_scaled_words_and_percentage(out, used_nc + used_c, cap, scale, 5); 150 out->print(" used, "); 151 print_scaled_words_and_percentage(out, free_and_waste_nc + free_and_waste_c, cap, scale, 5); 152 out->print(" free+waste, "); 153 print_scaled_words_and_percentage(out, overhead_nc + overhead_c, cap, scale, 5); 154 out->print(" overhead. "); 155 out->cr(); 156 } 157 158 out->cr(); 159 out->print_cr("Virtual space:"); 160 161 print_vs(out, scale); 162 163 out->cr(); 164 out->print_cr("Chunk freelists:"); 165 166 if (Metaspace::using_class_space()) { 167 out->print(" Non-Class: "); 168 } 169 print_human_readable_size(out, Metaspace::chunk_manager_metadata()->free_chunks_total_bytes(), scale); 170 out->cr(); 171 if (Metaspace::using_class_space()) { 172 out->print(" Class: "); 173 print_human_readable_size(out, Metaspace::chunk_manager_class()->free_chunks_total_bytes(), scale); 174 out->cr(); 175 out->print(" Both: "); 176 print_human_readable_size(out, Metaspace::chunk_manager_class()->free_chunks_total_bytes() + 177 Metaspace::chunk_manager_metadata()->free_chunks_total_bytes(), scale); 178 out->cr(); 179 } 180 181 out->cr(); 182 183 // Print basic settings 184 print_basic_switches(out, scale); 185 186 out->cr(); 187 188 } 189 190 void MetaspaceUtils::print_report(outputStream* out, size_t scale, int flags) { 191 192 if (!Metaspace::initialized()) { 193 out->print_cr("Metaspace not yet initialized."); 194 return; 195 } 196 197 const bool print_loaders = (flags & rf_show_loaders) > 0; 198 const bool print_classes = (flags & rf_show_classes) > 0; 199 const bool print_by_chunktype = (flags & rf_break_down_by_chunktype) > 0; 200 const bool print_by_spacetype = (flags & rf_break_down_by_spacetype) > 0; 201 202 // Some report options require walking the class loader data graph. 203 PrintCLDMetaspaceInfoClosure cl(out, scale, print_loaders, print_classes, print_by_chunktype); 204 if (print_loaders) { 205 out->cr(); 206 out->print_cr("Usage per loader:"); 207 out->cr(); 208 } 209 210 ClassLoaderDataGraph::loaded_cld_do(&cl); // collect data and optionally print 211 212 // Print totals, broken up by space type. 213 if (print_by_spacetype) { 214 out->cr(); 215 out->print_cr("Usage per space type:"); 216 out->cr(); 217 for (int space_type = (int)Metaspace::ZeroMetaspaceType; 218 space_type < (int)Metaspace::MetaspaceTypeCount; space_type ++) 219 { 220 uintx num_loaders = cl._num_loaders_by_spacetype[space_type]; 221 uintx num_classes = cl._num_classes_by_spacetype[space_type]; 222 out->print("%s - " UINTX_FORMAT " %s", 223 space_type_name((Metaspace::MetaspaceType)space_type), 224 num_loaders, loaders_plural(num_loaders)); 225 if (num_classes > 0) { 226 out->print(", "); 227 print_number_of_classes(out, num_classes, cl._num_classes_shared_by_spacetype[space_type]); 228 out->print(":"); 229 cl._stats_by_spacetype[space_type].print_on(out, scale, print_by_chunktype); 230 } else { 231 out->print("."); 232 out->cr(); 233 } 234 out->cr(); 235 } 236 } 237 238 // Print totals for in-use data: 239 out->cr(); 240 { 241 uintx num_loaders = cl._num_loaders; 242 out->print("Total Usage - " UINTX_FORMAT " %s, ", 243 num_loaders, loaders_plural(num_loaders)); 244 print_number_of_classes(out, cl._num_classes, cl._num_classes_shared); 245 out->print(":"); 246 cl._stats_total.print_on(out, scale, print_by_chunktype); 247 out->cr(); 248 } 249 250 // -- Print Virtual space. 251 out->cr(); 252 out->print_cr("Virtual space:"); 253 254 print_vs(out, scale); 255 256 // -- Print VirtualSpaceList details. 257 if ((flags & rf_show_vslist) > 0) { 258 out->cr(); 259 out->print_cr("Virtual space list%s:", Metaspace::using_class_space() ? "s" : ""); 260 261 if (Metaspace::using_class_space()) { 262 out->print_cr(" Non-Class:"); 263 } 264 Metaspace::space_list()->print_on(out, scale); 265 if (Metaspace::using_class_space()) { 266 out->print_cr(" Class:"); 267 Metaspace::class_space_list()->print_on(out, scale); 268 } 269 } 270 out->cr(); 271 272 // -- Print VirtualSpaceList map. 273 if ((flags & rf_show_vsmap) > 0) { 274 out->cr(); 275 out->print_cr("Virtual space map:"); 276 277 if (Metaspace::using_class_space()) { 278 out->print_cr(" Non-Class:"); 279 } 280 Metaspace::space_list()->print_map(out); 281 if (Metaspace::using_class_space()) { 282 out->print_cr(" Class:"); 283 Metaspace::class_space_list()->print_map(out); 284 } 285 } 286 out->cr(); 287 288 // -- Print Freelists (ChunkManager) details 289 out->cr(); 290 out->print_cr("Chunk freelist%s:", Metaspace::using_class_space() ? "s" : ""); 291 292 ChunkManagerStatistics non_class_cm_stat; 293 Metaspace::chunk_manager_metadata()->collect_statistics(&non_class_cm_stat); 294 295 if (Metaspace::using_class_space()) { 296 out->print_cr(" Non-Class:"); 297 } 298 non_class_cm_stat.print_on(out, scale); 299 300 if (Metaspace::using_class_space()) { 301 ChunkManagerStatistics class_cm_stat; 302 Metaspace::chunk_manager_class()->collect_statistics(&class_cm_stat); 303 out->print_cr(" Class:"); 304 class_cm_stat.print_on(out, scale); 305 } 306 307 // As a convenience, print a summary of common waste. 308 out->cr(); 309 out->print("Waste "); 310 // For all wastages, print percentages from total. As total use the total size of memory committed for metaspace. 311 const size_t committed_words = committed_bytes() / BytesPerWord; 312 313 out->print("(percentages refer to total committed size "); 314 print_scaled_words(out, committed_words, scale); 315 out->print_cr("):"); 316 317 // Print space committed but not yet used by any class loader 318 const size_t unused_words_in_vs = MetaspaceUtils::free_in_vs_bytes() / BytesPerWord; 319 out->print(" Committed unused: "); 320 print_scaled_words_and_percentage(out, unused_words_in_vs, committed_words, scale, 6); 321 out->cr(); 322 323 // Print waste for in-use chunks. 324 UsedChunksStatistics ucs_nonclass = cl._stats_total.nonclass_sm_stats().totals(); 325 UsedChunksStatistics ucs_class = cl._stats_total.class_sm_stats().totals(); 326 UsedChunksStatistics ucs_all; 327 ucs_all.add(ucs_nonclass); 328 ucs_all.add(ucs_class); 329 330 out->print(" Waste in chunks in use: "); 331 print_scaled_words_and_percentage(out, ucs_all.waste(), committed_words, scale, 6); 332 out->cr(); 333 out->print(" Free in chunks in use: "); 334 print_scaled_words_and_percentage(out, ucs_all.free(), committed_words, scale, 6); 335 out->cr(); 336 out->print(" Overhead in chunks in use: "); 337 print_scaled_words_and_percentage(out, ucs_all.overhead(), committed_words, scale, 6); 338 out->cr(); 339 340 // Print waste in free chunks. 341 const size_t total_capacity_in_free_chunks = 342 Metaspace::chunk_manager_metadata()->free_chunks_total_words() + 343 (Metaspace::using_class_space() ? Metaspace::chunk_manager_class()->free_chunks_total_words() : 0); 344 out->print(" In free chunks: "); 345 print_scaled_words_and_percentage(out, total_capacity_in_free_chunks, committed_words, scale, 6); 346 out->cr(); 347 348 // Print waste in deallocated blocks. 349 const uintx free_blocks_num = 350 cl._stats_total.nonclass_sm_stats().free_blocks_num() + 351 cl._stats_total.class_sm_stats().free_blocks_num(); 352 const size_t free_blocks_cap_words = 353 cl._stats_total.nonclass_sm_stats().free_blocks_cap_words() + 354 cl._stats_total.class_sm_stats().free_blocks_cap_words(); 355 out->print("Deallocated from chunks in use: "); 356 print_scaled_words_and_percentage(out, free_blocks_cap_words, committed_words, scale, 6); 357 out->print(" (" UINTX_FORMAT " blocks)", free_blocks_num); 358 out->cr(); 359 360 // Print total waste. 361 const size_t total_waste = ucs_all.waste() + ucs_all.free() + ucs_all.overhead() + total_capacity_in_free_chunks 362 + free_blocks_cap_words + unused_words_in_vs; 363 out->print(" -total-: "); 364 print_scaled_words_and_percentage(out, total_waste, committed_words, scale, 6); 365 out->cr(); 366 367 // Print internal statistics 368 #ifdef ASSERT 369 out->cr(); 370 out->cr(); 371 out->print_cr("Internal statistics:"); 372 out->cr(); 373 out->print_cr("Number of allocations: " UINTX_FORMAT ".", g_internal_statistics.num_allocs); 374 out->print_cr("Number of space births: " UINTX_FORMAT ".", g_internal_statistics.num_metaspace_births); 375 out->print_cr("Number of space deaths: " UINTX_FORMAT ".", g_internal_statistics.num_metaspace_deaths); 376 out->print_cr("Number of virtual space node births: " UINTX_FORMAT ".", g_internal_statistics.num_vsnodes_created); 377 out->print_cr("Number of virtual space node deaths: " UINTX_FORMAT ".", g_internal_statistics.num_vsnodes_purged); 378 out->print_cr("Number of times virtual space nodes were expanded: " UINTX_FORMAT ".", g_internal_statistics.num_committed_space_expanded); 379 out->print_cr("Number of deallocations: " UINTX_FORMAT " (" UINTX_FORMAT " external).", g_internal_statistics.num_deallocs, g_internal_statistics.num_external_deallocs); 380 out->print_cr("Allocations from deallocated blocks: " UINTX_FORMAT ".", g_internal_statistics.num_allocs_from_deallocated_blocks); 381 out->print_cr("Number of chunks added to freelist: " UINTX_FORMAT ".", 382 g_internal_statistics.num_chunks_added_to_freelist); 383 out->print_cr("Number of chunks removed from freelist: " UINTX_FORMAT ".", 384 g_internal_statistics.num_chunks_removed_from_freelist); 385 out->print_cr("Number of chunk merges: " UINTX_FORMAT ", split-ups: " UINTX_FORMAT ".", 386 g_internal_statistics.num_chunk_merges, g_internal_statistics.num_chunk_splits); 387 388 out->cr(); 389 #endif 390 391 // Print some interesting settings 392 out->cr(); 393 out->cr(); 394 print_basic_switches(out, scale); 395 396 out->cr(); 397 out->print("InitialBootClassLoaderMetaspaceSize: "); 398 print_human_readable_size(out, InitialBootClassLoaderMetaspaceSize, scale); 399 400 out->cr(); 401 out->cr(); 402 403 } // MetaspaceUtils::print_report() 404 405 } // namespace metaspace 406