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