< prev index next >

src/hotspot/share/memory/metaspace/metaspaceStatistics.cpp

Print this page
rev 60538 : imported patch jep387-core.patch
   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 #include "memory/metaspace/metachunk.hpp"

  28 #include "memory/metaspace/metaspaceCommon.hpp"
  29 #include "memory/metaspace/metaspaceStatistics.hpp"

  30 #include "utilities/debug.hpp"
  31 #include "utilities/globalDefinitions.hpp"
  32 #include "utilities/ostream.hpp"
  33 
  34 namespace metaspace {
  35 
  36 // FreeChunksStatistics methods
  37 
  38 FreeChunksStatistics::FreeChunksStatistics()
  39 : _num(0), _cap(0)
  40 {}
  41 
  42 void FreeChunksStatistics::reset() {
  43   _num = 0; _cap = 0;
  44 }
  45 
  46 void FreeChunksStatistics::add(uintx n, size_t s) {
  47   _num += n; _cap += s;





  48 }
  49 
  50 void FreeChunksStatistics::add(const FreeChunksStatistics& other) {
  51   _num += other._num;
  52   _cap += other._cap;




  53 }
  54 
  55 void FreeChunksStatistics::print_on(outputStream* st, size_t scale) const {
  56   st->print(UINTX_FORMAT, _num);
  57   st->print(" chunks, total capacity ");
  58   print_scaled_words(st, _cap, scale);
  59 }
  60 
  61 // ChunkManagerStatistics methods









  62 
  63 void ChunkManagerStatistics::reset() {
  64   for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
  65     _chunk_stats[i].reset();
  66   }
  67 }
  68 
  69 size_t ChunkManagerStatistics::total_capacity() const {
  70   return _chunk_stats[SpecializedIndex].cap() +
  71       _chunk_stats[SmallIndex].cap() +
  72       _chunk_stats[MediumIndex].cap() +
  73       _chunk_stats[HumongousIndex].cap();
  74 }
  75 
  76 void ChunkManagerStatistics::print_on(outputStream* st, size_t scale) const {
  77   FreeChunksStatistics totals;
  78   for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
  79     st->cr();
  80     st->print("%12s chunks: ", chunk_size_name(i));
  81     if (_chunk_stats[i].num() > 0) {
  82       st->print(UINTX_FORMAT_W(4) ", capacity ", _chunk_stats[i].num());
  83       print_scaled_words(st, _chunk_stats[i].cap(), scale);
  84     } else {
  85       st->print("(none)");
  86     }
  87     totals.add(_chunk_stats[i]);
  88   }
  89   st->cr();
  90   st->print("%19s: " UINTX_FORMAT_W(4) ", capacity=", "Total", totals.num());
  91   print_scaled_words(st, totals.cap(), scale);


  92   st->cr();
  93 }
  94 
  95 // UsedChunksStatistics methods
  96 
  97 UsedChunksStatistics::UsedChunksStatistics()
  98 : _num(0), _cap(0), _used(0), _free(0), _waste(0), _overhead(0)
  99 {}
 100 
 101 void UsedChunksStatistics::reset() {
 102   _num = 0;
 103   _cap = _overhead = _used = _free = _waste = 0;
 104 }

 105 
 106 void UsedChunksStatistics::add(const UsedChunksStatistics& other) {
 107   _num += other._num;
 108   _cap += other._cap;
 109   _used += other._used;
 110   _free += other._free;
 111   _waste += other._waste;
 112   _overhead += other._overhead;
 113   DEBUG_ONLY(check_sanity());
 114 }
 115 
 116 void UsedChunksStatistics::print_on(outputStream* st, size_t scale) const {
 117   int col = st->position();
 118   st->print(UINTX_FORMAT_W(4) " chunk%s, ", _num, _num != 1 ? "s" : "");
 119   if (_num > 0) {
 120     col += 14; st->fill_to(col);
 121 
 122     print_scaled_words(st, _cap, scale, 5);
 123     st->print(" capacity, ");




 124 
 125     col += 18; st->fill_to(col);
 126     print_scaled_words_and_percentage(st, _used, _cap, scale, 5);
 127     st->print(" used, ");
 128 
 129     col += 20; st->fill_to(col);
 130     print_scaled_words_and_percentage(st, _free, _cap, scale, 5);
 131     st->print(" free, ");
 132 
 133     col += 20; st->fill_to(col);
 134     print_scaled_words_and_percentage(st, _waste, _cap, scale, 5);
 135     st->print(" waste, ");
 136 
 137     col += 20; st->fill_to(col);
 138     print_scaled_words_and_percentage(st, _overhead, _cap, scale, 5);
 139     st->print(" overhead");
 140   }
 141   DEBUG_ONLY(check_sanity());
 142 }
 143 
 144 #ifdef ASSERT
 145 void UsedChunksStatistics::check_sanity() const {
 146   assert(_overhead == (Metachunk::overhead() * _num), "Sanity: Overhead.");
 147   assert(_cap == _used + _free + _waste + _overhead, "Sanity: Capacity.");


 148 }
 149 #endif
 150 
 151 // SpaceManagerStatistics methods
 152 
 153 SpaceManagerStatistics::SpaceManagerStatistics() { reset(); }
 154 
 155 void SpaceManagerStatistics::reset() {
 156   for (int i = 0; i < NumberOfInUseLists; i ++) {
 157     _chunk_stats[i].reset();
 158     _free_blocks_num = 0; _free_blocks_cap_words = 0;
 159   }


 160 }
 161 
 162 void SpaceManagerStatistics::add_free_blocks_info(uintx num, size_t cap) {
 163   _free_blocks_num += num;
 164   _free_blocks_cap_words += cap;
 165 }
 166 
 167 void SpaceManagerStatistics::add(const SpaceManagerStatistics& other) {
 168   for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
 169     _chunk_stats[i].add(other._chunk_stats[i]);
 170   }
 171   _free_blocks_num += other._free_blocks_num;
 172   _free_blocks_cap_words += other._free_blocks_cap_words;
 173 }
 174 
 175 // Returns total chunk statistics over all chunk types.
 176 UsedChunksStatistics SpaceManagerStatistics::totals() const {
 177   UsedChunksStatistics stat;
 178   for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
 179     stat.add(_chunk_stats[i]);
 180   }
 181   return stat;
 182 }
 183 
 184 void SpaceManagerStatistics::print_on(outputStream* st, size_t scale,  bool detailed) const {
 185   streamIndentor sti(st);
 186   if (detailed) {
 187     st->cr_indent();
 188     st->print("Usage by chunk type:");
 189     {
 190       streamIndentor sti2(st);
 191       for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
 192         st->cr_indent();
 193         st->print("%15s: ", chunk_size_name(i));
 194         if (_chunk_stats[i].num() == 0) {

 195           st->print(" (none)");
 196         } else {
 197           _chunk_stats[i].print_on(st, scale);
 198         }
 199       }
 200 
 201       st->cr_indent();
 202       st->print("%15s: ", "-total-");
 203       totals().print_on(st, scale);
 204     }
 205     if (_free_blocks_num > 0) {
 206       st->cr_indent();
 207       st->print("deallocated: " UINTX_FORMAT " blocks with ", _free_blocks_num);
 208       print_scaled_words(st, _free_blocks_cap_words, scale);
 209     }
 210   } else {
 211     totals().print_on(st, scale);
 212     st->print(", ");
 213     st->print("deallocated: " UINTX_FORMAT " blocks with ", _free_blocks_num);
 214     print_scaled_words(st, _free_blocks_cap_words, scale);
 215   }
 216 }
 217 
 218 // ClassLoaderMetaspaceStatistics methods
 219 
 220 ClassLoaderMetaspaceStatistics::ClassLoaderMetaspaceStatistics() { reset(); }
 221 
 222 void ClassLoaderMetaspaceStatistics::reset() {
 223   nonclass_sm_stats().reset();
 224   if (Metaspace::using_class_space()) {
 225     class_sm_stats().reset();
 226   }




 227 }

 228 
 229 // Returns total space manager statistics for both class and non-class metaspace
 230 SpaceManagerStatistics ClassLoaderMetaspaceStatistics::totals() const {
 231   SpaceManagerStatistics stats;
 232   stats.add(nonclass_sm_stats());
 233   if (Metaspace::using_class_space()) {
 234     stats.add(class_sm_stats());
 235   }
 236   return stats;
 237 }
 238 
 239 void ClassLoaderMetaspaceStatistics::add(const ClassLoaderMetaspaceStatistics& other) {
 240   nonclass_sm_stats().add(other.nonclass_sm_stats());
 241   if (Metaspace::using_class_space()) {
 242     class_sm_stats().add(other.class_sm_stats());
 243   }

 244 }
 245 
 246 void ClassLoaderMetaspaceStatistics::print_on(outputStream* st, size_t scale, bool detailed) const {
 247   streamIndentor sti(st);
 248   st->cr_indent();
 249   if (Metaspace::using_class_space()) {
 250     st->print("Non-Class: ");
 251   }
 252   nonclass_sm_stats().print_on(st, scale, detailed);
 253   if (detailed) {
 254     st->cr();
 255   }
 256   if (Metaspace::using_class_space()) {
 257     st->cr_indent();
 258     st->print("    Class: ");
 259     class_sm_stats().print_on(st, scale, detailed);
 260     if (detailed) {
 261       st->cr();
 262     }
 263     st->cr_indent();
 264     st->print("     Both: ");
 265     totals().print_on(st, scale, detailed);
 266     if (detailed) {
 267       st->cr();
 268     }
 269   }
 270   st->cr();
 271 }








 272 
 273 } // end namespace metaspace
 274 
 275 
 276 
   1 /*
   2  * Copyright (c) 2018, 2020, 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 
  28 
  29 #include "memory/metaspace/chunkLevel.hpp"
  30 #include "memory/metaspace/metaspaceCommon.hpp"
  31 #include "memory/metaspace/metaspaceStatistics.hpp"
  32 
  33 #include "utilities/debug.hpp"
  34 #include "utilities/globalDefinitions.hpp"
  35 #include "utilities/ostream.hpp"
  36 
  37 namespace metaspace {
  38 

  39 
  40 // Returns total word size of all chunks in this manager.
  41 void cm_stats_t::add(const cm_stats_t& other) {
  42   for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l ++) {
  43     num_chunks[l] += other.num_chunks[l];
  44     committed_word_size[l] += other.committed_word_size[l];
  45   }
  46 }
  47 
  48 // Returns total word size of all chunks in this manager.
  49 size_t cm_stats_t::total_word_size() const {
  50   size_t s = 0;
  51   for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l ++) {
  52     s += num_chunks[l] * chunklevel::word_size_for_level(l);
  53   }
  54   return s;
  55 }
  56 
  57 // Returns total committed word size of all chunks in this manager.
  58 size_t cm_stats_t::total_committed_word_size() const {
  59   size_t s = 0;
  60   for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l ++) {
  61     s += committed_word_size[l];
  62   }
  63   return s;
  64 }
  65 





  66 
  67 void cm_stats_t::print_on(outputStream* st, size_t scale) const {
  68   // Note: used as part of MetaspaceReport so formatting matters.
  69   size_t total_size = 0;
  70   size_t total_committed_size = 0;
  71   for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l ++) {
  72     st->cr();
  73     chunklevel::print_chunk_size(st, l);
  74     st->print(": ");
  75     if (num_chunks[l] > 0) {
  76       const size_t word_size = num_chunks[l] * chunklevel::word_size_for_level(l);
  77 
  78       st->print("%4d, capacity=", num_chunks[l]);
  79       print_scaled_words(st, word_size, scale);



  80 
  81       st->print(", committed=");
  82       print_scaled_words_and_percentage(st, committed_word_size[l], word_size, scale);




  83 
  84       total_size += word_size;
  85       total_committed_size += committed_word_size[l];






  86     } else {
  87       st->print("(none)");
  88     }

  89   }
  90   st->cr();
  91   st->print("Total word size: ");
  92   print_scaled_words(st, total_size, scale);
  93   st->print(", committed: ");
  94   print_scaled_words_and_percentage(st, total_committed_size, total_size, scale);
  95   st->cr();
  96 }
  97 
  98 #ifdef ASSERT
  99 void cm_stats_t::verify() const {
 100   assert(total_committed_word_size() <= total_word_size(),
 101          "Sanity");





 102 }
 103 #endif
 104 









 105 
 106 void in_use_chunk_stats_t::print_on(outputStream* st, size_t scale) const {
 107   int col = st->position();
 108   st->print("%4d chunk%s, ", num, num != 1 ? "s" : "");
 109   if (num > 0) {
 110     col += 14; st->fill_to(col);
 111 
 112     print_scaled_words(st, word_size, scale, 5);
 113     st->print(" capacity,");
 114 
 115     col += 20; st->fill_to(col);
 116     print_scaled_words_and_percentage(st, committed_words, word_size, scale, 5);
 117     st->print(" committed, ");
 118 
 119     col += 18; st->fill_to(col);
 120     print_scaled_words_and_percentage(st, used_words, word_size, scale, 5);
 121     st->print(" used, ");
 122 
 123     col += 20; st->fill_to(col);
 124     print_scaled_words_and_percentage(st, free_words, word_size, scale, 5);
 125     st->print(" free, ");
 126 
 127     col += 20; st->fill_to(col);
 128     print_scaled_words_and_percentage(st, waste_words, word_size, scale, 5);
 129     st->print(" waste ");
 130 



 131   }

 132 }
 133 
 134 #ifdef ASSERT
 135 void in_use_chunk_stats_t::verify() const {
 136   assert(word_size >= committed_words &&
 137       committed_words == used_words + free_words + waste_words,
 138          "Sanity: cap " SIZE_FORMAT ", committed " SIZE_FORMAT ", used " SIZE_FORMAT ", free " SIZE_FORMAT ", waste " SIZE_FORMAT ".",
 139          word_size, committed_words, used_words, free_words, waste_words);
 140 }
 141 #endif
 142 
 143 void arena_stats_t::add(const arena_stats_t& other) {
 144   for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l ++) {
 145     stats[l].add(other.stats[l]);





 146   }
 147   free_blocks_num += other.free_blocks_num;
 148   free_blocks_word_size += other.free_blocks_word_size;
 149 }
 150 












 151 
 152 // Returns total chunk statistics over all chunk types.
 153 in_use_chunk_stats_t arena_stats_t::totals() const {
 154   in_use_chunk_stats_t out;
 155   for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l ++) {
 156     out.add(stats[l]);
 157   }
 158   return out;
 159 }
 160 
 161 void arena_stats_t::print_on(outputStream* st, size_t scale,  bool detailed) const {
 162   streamIndentor sti(st);
 163   if (detailed) {
 164     st->cr_indent();
 165     st->print("Usage by chunk level:");
 166     {
 167       streamIndentor sti2(st);
 168       for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l ++) {
 169         st->cr_indent();
 170         chunklevel::print_chunk_size(st, l);
 171         st->print(" chunks: ");
 172         if (stats[l].num == 0) {
 173           st->print(" (none)");
 174         } else {
 175           stats[l].print_on(st, scale);
 176         }
 177       }
 178 
 179       st->cr_indent();
 180       st->print("%15s: ", "-total-");
 181       totals().print_on(st, scale);
 182     }
 183     if (free_blocks_num > 0) {
 184       st->cr_indent();
 185       st->print("deallocated: " UINTX_FORMAT " blocks with ", free_blocks_num);
 186       print_scaled_words(st, free_blocks_word_size, scale);
 187     }
 188   } else {
 189     totals().print_on(st, scale);
 190     st->print(", ");
 191     st->print("deallocated: " UINTX_FORMAT " blocks with ", free_blocks_num);
 192     print_scaled_words(st, free_blocks_word_size, scale);
 193   }
 194 }
 195 
 196 #ifdef ASSERT


 197 
 198 void arena_stats_t::verify() const {
 199   size_t total_used = 0;
 200   for (chunklevel_t l = chunklevel::LOWEST_CHUNK_LEVEL; l <= chunklevel::HIGHEST_CHUNK_LEVEL; l ++) {
 201     stats[l].verify();
 202     total_used += stats[l].used_words;
 203   }
 204   // Deallocated allocations still count as used
 205   assert(total_used >= free_blocks_word_size,
 206          "Sanity");
 207 }
 208 #endif
 209 









 210 
 211 // Returns total arena statistics for both class and non-class metaspace
 212 arena_stats_t clms_stats_t::totals() const {
 213   arena_stats_t out;
 214   out.add(arena_stats_nonclass);
 215   out.add(arena_stats_class);
 216   return out;
 217 }
 218 
 219 void clms_stats_t::print_on(outputStream* st, size_t scale, bool detailed) const {
 220   streamIndentor sti(st);
 221   st->cr_indent();
 222   if (Metaspace::using_class_space()) {
 223     st->print("Non-Class: ");
 224   }
 225   arena_stats_nonclass.print_on(st, scale, detailed);
 226   if (detailed) {
 227     st->cr();
 228   }
 229   if (Metaspace::using_class_space()) {
 230     st->cr_indent();
 231     st->print("    Class: ");
 232     arena_stats_class.print_on(st, scale, detailed);
 233     if (detailed) {
 234       st->cr();
 235     }
 236     st->cr_indent();
 237     st->print("     Both: ");
 238     totals().print_on(st, scale, detailed);
 239     if (detailed) {
 240       st->cr();
 241     }
 242   }
 243   st->cr();
 244 }
 245 
 246 
 247 #ifdef ASSERT
 248 void clms_stats_t::verify() const {
 249   arena_stats_nonclass.verify();
 250   arena_stats_class.verify();
 251 }
 252 #endif
 253 
 254 } // end namespace metaspace
 255 
 256 
 257 
< prev index next >