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