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 // 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
|