rev 57380 : [mq]: metaspace-improvement
1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2018 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 #include "precompiled.hpp" 26 27 28 #include "memory/metaspace/chunkLevel.hpp" 29 #include "memory/metaspace/metaspaceCommon.hpp" 30 #include "memory/metaspace/metaspaceStatistics.hpp" 31 32 #include "utilities/debug.hpp" 33 #include "utilities/globalDefinitions.hpp" 34 #include "utilities/ostream.hpp" 35 36 namespace metaspace { 37 38 // FreeChunksStatistics methods 39 40 void FreeChunksStatistics::print_on(outputStream* st, size_t scale) const { 41 st->print(UINTX_FORMAT, num); 42 st->print(" chunks, total capacity "); 43 print_scaled_words(st, word_size, scale); 44 } 45 46 // ChunkManagerStatistics methods 47 48 void ChunkManagerStatistics::reset() { 49 for (chklvl_t l = chklvl::LOWEST_CHUNK_LEVEL; l <= chklvl::HIGHEST_CHUNK_LEVEL; l ++) { 50 chunk_stats[l].reset(); 51 } 52 } 53 54 size_t ChunkManagerStatistics::total_capacity() const { 55 size_t cap = 0; 56 for (chklvl_t l = chklvl::LOWEST_CHUNK_LEVEL; l <= chklvl::HIGHEST_CHUNK_LEVEL; l ++) { 57 cap += chunk_stats[l].word_size; 58 } 59 } 60 61 void ChunkManagerStatistics::print_on(outputStream* st, size_t scale) const { 62 FreeChunksStatistics totals; 63 totals.reset(); 64 for (chklvl_t l = chklvl::LOWEST_CHUNK_LEVEL; l <= chklvl::HIGHEST_CHUNK_LEVEL; l ++) { 65 st->cr(); 66 st->print(SIZE_FORMAT "k chunks: ", (chklvl::word_size_for_level(l) * BytesPerWord) / K); 67 if (chunk_stats[l].num > 0) { 68 st->print(UINTX_FORMAT_W(4) ", capacity ", chunk_stats[l].num); 69 print_scaled_words(st, chunk_stats[l].word_size, scale); 70 } else { 71 st->print("(none)"); 72 } 73 totals.add(chunk_stats[l]); 74 } 75 st->cr(); 76 st->print("Total: " UINTX_FORMAT_W(4) ", capacity=", totals.num()); 77 print_scaled_words(st, totals.word_size, scale); 78 st->cr(); 79 } 80 81 // UsedChunksStatistics methods 82 83 void UsedChunksStatistics::print_on(outputStream* st, size_t scale) const { 84 int col = st->position(); 85 st->print(UINTX_FORMAT_W(4) " chunk%s, ", num, num != 1 ? "s" : ""); 86 if (num > 0) { 87 col += 14; st->fill_to(col); 88 89 print_scaled_words(st, cap, scale, 5); 90 st->print(" capacity, "); 91 92 col += 18; st->fill_to(col); 93 print_scaled_words_and_percentage(st, used, cap, scale, 5); 94 st->print(" used, "); 95 96 col += 20; st->fill_to(col); 97 print_scaled_words_and_percentage(st, free, cap, scale, 5); 98 st->print(" free, "); 99 100 col += 20; st->fill_to(col); 101 print_scaled_words_and_percentage(st, waste, cap, scale, 5); 102 st->print(" waste "); 103 104 } 105 DEBUG_ONLY(check_sanity()); 106 } 107 108 #ifdef ASSERT 109 void UsedChunksStatistics::check_sanity() const { 110 assert(cap == used + free + waste, "Sanity: Capacity."); 111 } 112 #endif 113 114 // SpaceManagerStatistics methods 115 116 SpaceManagerStatistics::SpaceManagerStatistics() { reset(); } 117 118 void SpaceManagerStatistics::reset() { 119 for (chklvl_t l = chklvl::LOWEST_CHUNK_LEVEL; l <= chklvl::HIGHEST_CHUNK_LEVEL; l ++) { 120 chunk_stats[l].reset(); 121 } 122 free_blocks_num = 0; 123 free_blocks_word_size = 0; 124 } 125 126 void SpaceManagerStatistics::add(const SpaceManagerStatistics& other) { 127 for (chklvl_t l = chklvl::LOWEST_CHUNK_LEVEL; l <= chklvl::HIGHEST_CHUNK_LEVEL; l ++) { 128 chunk_stats[l].add(other.chunk_stats[l]); 129 } 130 free_blocks_num += other.free_blocks_num; 131 free_blocks_word_size += other.free_blocks_word_size; 132 } 133 134 // Returns total chunk statistics over all chunk types. 135 UsedChunksStatistics SpaceManagerStatistics::totals() const { 136 UsedChunksStatistics stat; 137 stat.reset(); 138 for (chklvl_t l = chklvl::LOWEST_CHUNK_LEVEL; l <= chklvl::HIGHEST_CHUNK_LEVEL; l ++) { 139 stat.add(chunk_stats[l]); 140 } 141 return stat; 142 } 143 144 void SpaceManagerStatistics::print_on(outputStream* st, size_t scale, bool detailed) const { 145 streamIndentor sti(st); 146 if (detailed) { 147 st->cr_indent(); 148 st->print("Usage by chunk level:"); 149 { 150 streamIndentor sti2(st); 151 for (chklvl_t l = chklvl::LOWEST_CHUNK_LEVEL; l <= chklvl::HIGHEST_CHUNK_LEVEL; l ++) { 152 st->cr_indent(); 153 st->print(SIZE_FORMAT "k chunks: ", (chklvl::word_size_for_level(l) * BytesPerWord) / K); 154 if (chunk_stats[l].num == 0) { 155 st->print(" (none)"); 156 } else { 157 chunk_stats[l].print_on(st, scale); 158 } 159 } 160 161 st->cr_indent(); 162 st->print("%15s: ", "-total-"); 163 totals().print_on(st, scale); 164 } 165 if (free_blocks_num > 0) { 166 st->cr_indent(); 167 st->print("deallocated: " UINTX_FORMAT " blocks with ", free_blocks_num); 168 print_scaled_words(st, free_blocks_word_size, scale); 169 } 170 } else { 171 totals().print_on(st, scale); 172 st->print(", "); 173 st->print("deallocated: " UINTX_FORMAT " blocks with ", free_blocks_num); 174 print_scaled_words(st, free_blocks_word_size, scale); 175 } 176 } 177 178 // ClassLoaderMetaspaceStatistics methods 179 180 // Returns total space manager statistics for both class and non-class metaspace 181 SpaceManagerStatistics ClassLoaderMetaspaceStatistics::totals() const { 182 SpaceManagerStatistics stats; 183 stats.reset(); 184 stats.add(sm_stats[Metaspace::ClassType]); 185 stats.add(sm_stats[Metaspace::NonClassType]); 186 return stats; 187 } 188 189 void ClassLoaderMetaspaceStatistics::print_on(outputStream* st, size_t scale, bool detailed) const { 190 streamIndentor sti(st); 191 st->cr_indent(); 192 if (Metaspace::using_class_space()) { 193 st->print("Non-Class: "); 194 } 195 sm_stats[Metaspace::NonClassType].print_on(st, scale, detailed); 196 if (detailed) { 197 st->cr(); 198 } 199 if (Metaspace::using_class_space()) { 200 st->cr_indent(); 201 st->print(" Class: "); 202 sm_stats[Metaspace::ClassType].print_on(st, scale, detailed); 203 if (detailed) { 204 st->cr(); 205 } 206 st->cr_indent(); 207 st->print(" Both: "); 208 totals().print_on(st, scale, detailed); 209 if (detailed) { 210 st->cr(); 211 } 212 } 213 st->cr(); 214 } 215 216 } // end namespace metaspace 217 218 219 --- EOF ---