Mercurial > hg > graal-jvmci-8
annotate src/share/vm/memory/heapInspection.cpp @ 10241:d17700c82d7d
8006088: Incompatible heap size flags accepted by VM
Summary: Make processing of minimum, initial and maximum heap size more intiutive by removing previous limitations on allowed values, and make error reporting consistent. Further, fix errors in ergonomic heap sizing.
Reviewed-by: johnc, jwilhelm, tamao
author | tschatzl |
---|---|
date | Mon, 06 May 2013 17:19:42 +0200 |
parents | 3c9bc17b9403 |
children | 92ef81e2f571 |
rev | line source |
---|---|
0 | 1 /* |
7956 | 2 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
7956 | 26 #include "classfile/classLoaderData.hpp" |
1972 | 27 #include "gc_interface/collectedHeap.hpp" |
28 #include "memory/genCollectedHeap.hpp" | |
29 #include "memory/heapInspection.hpp" | |
30 #include "memory/resourceArea.hpp" | |
31 #include "runtime/os.hpp" | |
32 #include "utilities/globalDefinitions.hpp" | |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
6725
diff
changeset
|
33 #include "utilities/macros.hpp" |
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
6725
diff
changeset
|
34 #if INCLUDE_ALL_GCS |
1972 | 35 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
6725
diff
changeset
|
36 #endif // INCLUDE_ALL_GCS |
0 | 37 |
38 // HeapInspection | |
39 | |
40 int KlassInfoEntry::compare(KlassInfoEntry* e1, KlassInfoEntry* e2) { | |
41 if(e1->_instance_words > e2->_instance_words) { | |
42 return -1; | |
43 } else if(e1->_instance_words < e2->_instance_words) { | |
44 return 1; | |
45 } | |
7956 | 46 // Sort alphabetically, note 'Z' < '[' < 'a', but it's better to group |
47 // the array classes before all the instance classes. | |
48 ResourceMark rm; | |
49 const char* name1 = e1->klass()->external_name(); | |
50 const char* name2 = e2->klass()->external_name(); | |
51 bool d1 = (name1[0] == '['); | |
52 bool d2 = (name2[0] == '['); | |
53 if (d1 && !d2) { | |
54 return -1; | |
55 } else if (d2 && !d1) { | |
56 return 1; | |
57 } else { | |
58 return strcmp(name1, name2); | |
59 } | |
0 | 60 } |
61 | |
7956 | 62 const char* KlassInfoEntry::name() const { |
63 const char* name; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
64 if (_klass->name() != NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
65 name = _klass->external_name(); |
0 | 66 } else { |
67 if (_klass == Universe::boolArrayKlassObj()) name = "<boolArrayKlass>"; else | |
68 if (_klass == Universe::charArrayKlassObj()) name = "<charArrayKlass>"; else | |
69 if (_klass == Universe::singleArrayKlassObj()) name = "<singleArrayKlass>"; else | |
70 if (_klass == Universe::doubleArrayKlassObj()) name = "<doubleArrayKlass>"; else | |
71 if (_klass == Universe::byteArrayKlassObj()) name = "<byteArrayKlass>"; else | |
72 if (_klass == Universe::shortArrayKlassObj()) name = "<shortArrayKlass>"; else | |
73 if (_klass == Universe::intArrayKlassObj()) name = "<intArrayKlass>"; else | |
74 if (_klass == Universe::longArrayKlassObj()) name = "<longArrayKlass>"; else | |
75 name = "<no name>"; | |
76 } | |
7956 | 77 return name; |
78 } | |
79 | |
80 void KlassInfoEntry::print_on(outputStream* st) const { | |
81 ResourceMark rm; | |
82 | |
0 | 83 // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
84 st->print_cr(INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13) " %s", |
0 | 85 (jlong) _instance_count, |
86 (julong) _instance_words * HeapWordSize, | |
7956 | 87 name()); |
0 | 88 } |
89 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
90 KlassInfoEntry* KlassInfoBucket::lookup(Klass* const k) { |
0 | 91 KlassInfoEntry* elt = _list; |
92 while (elt != NULL) { | |
93 if (elt->is_equal(k)) { | |
94 return elt; | |
95 } | |
96 elt = elt->next(); | |
97 } | |
98 elt = new KlassInfoEntry(k, list()); | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
99 // We may be out of space to allocate the new entry. |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
100 if (elt != NULL) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
101 set_list(elt); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
102 } |
0 | 103 return elt; |
104 } | |
105 | |
106 void KlassInfoBucket::iterate(KlassInfoClosure* cic) { | |
107 KlassInfoEntry* elt = _list; | |
108 while (elt != NULL) { | |
109 cic->do_cinfo(elt); | |
110 elt = elt->next(); | |
111 } | |
112 } | |
113 | |
114 void KlassInfoBucket::empty() { | |
115 KlassInfoEntry* elt = _list; | |
116 _list = NULL; | |
117 while (elt != NULL) { | |
118 KlassInfoEntry* next = elt->next(); | |
119 delete elt; | |
120 elt = next; | |
121 } | |
122 } | |
123 | |
7956 | 124 void KlassInfoTable::AllClassesFinder::do_klass(Klass* k) { |
125 // This has the SIDE EFFECT of creating a KlassInfoEntry | |
126 // for <k>, if one doesn't exist yet. | |
127 _table->lookup(k); | |
128 } | |
129 | |
130 KlassInfoTable::KlassInfoTable(int size, HeapWord* ref, | |
131 bool need_class_stats) { | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
132 _size = 0; |
0 | 133 _ref = ref; |
6197 | 134 _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size, mtInternal); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
135 if (_buckets != NULL) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
136 _size = size; |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
137 for (int index = 0; index < _size; index++) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
138 _buckets[index].initialize(); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
139 } |
7956 | 140 if (need_class_stats) { |
141 AllClassesFinder finder(this); | |
142 ClassLoaderDataGraph::classes_do(&finder); | |
143 } | |
0 | 144 } |
145 } | |
146 | |
147 KlassInfoTable::~KlassInfoTable() { | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
148 if (_buckets != NULL) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
149 for (int index = 0; index < _size; index++) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
150 _buckets[index].empty(); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
151 } |
6197 | 152 FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets, mtInternal); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
153 _size = 0; |
0 | 154 } |
155 } | |
156 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
157 uint KlassInfoTable::hash(Klass* p) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
158 assert(p->is_metadata(), "all klasses are metadata"); |
0 | 159 return (uint)(((uintptr_t)p - (uintptr_t)_ref) >> 2); |
160 } | |
161 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
162 KlassInfoEntry* KlassInfoTable::lookup(Klass* const k) { |
0 | 163 uint idx = hash(k) % _size; |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
164 assert(_buckets != NULL, "Allocation failure should have been caught"); |
0 | 165 KlassInfoEntry* e = _buckets[idx].lookup(k); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
166 // Lookup may fail if this is a new klass for which we |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
167 // could not allocate space for an new entry. |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
168 assert(e == NULL || k == e->klass(), "must be equal"); |
0 | 169 return e; |
170 } | |
171 | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
172 // Return false if the entry could not be recorded on account |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
173 // of running out of space required to create a new entry. |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
174 bool KlassInfoTable::record_instance(const oop obj) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
175 Klass* k = obj->klass(); |
0 | 176 KlassInfoEntry* elt = lookup(k); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
177 // elt may be NULL if it's a new klass for which we |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
178 // could not allocate space for a new entry in the hashtable. |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
179 if (elt != NULL) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
180 elt->set_count(elt->count() + 1); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
181 elt->set_words(elt->words() + obj->size()); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
182 return true; |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
183 } else { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
184 return false; |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
185 } |
0 | 186 } |
187 | |
188 void KlassInfoTable::iterate(KlassInfoClosure* cic) { | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
189 assert(_size == 0 || _buckets != NULL, "Allocation failure should have been caught"); |
0 | 190 for (int index = 0; index < _size; index++) { |
191 _buckets[index].iterate(cic); | |
192 } | |
193 } | |
194 | |
195 int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) { | |
196 return (*e1)->compare(*e1,*e2); | |
197 } | |
198 | |
7956 | 199 KlassInfoHisto::KlassInfoHisto(KlassInfoTable* cit, const char* title, int estimatedCount) : |
200 _cit(cit), | |
0 | 201 _title(title) { |
6197 | 202 _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(estimatedCount,true); |
0 | 203 } |
204 | |
205 KlassInfoHisto::~KlassInfoHisto() { | |
206 delete _elements; | |
207 } | |
208 | |
209 void KlassInfoHisto::add(KlassInfoEntry* cie) { | |
210 elements()->append(cie); | |
211 } | |
212 | |
213 void KlassInfoHisto::sort() { | |
214 elements()->sort(KlassInfoHisto::sort_helper); | |
215 } | |
216 | |
217 void KlassInfoHisto::print_elements(outputStream* st) const { | |
218 // simplify the formatting (ILP32 vs LP64) - store the sum in 64-bit | |
219 jlong total = 0; | |
220 julong totalw = 0; | |
221 for(int i=0; i < elements()->length(); i++) { | |
222 st->print("%4d: ", i+1); | |
223 elements()->at(i)->print_on(st); | |
224 total += elements()->at(i)->count(); | |
225 totalw += elements()->at(i)->words(); | |
226 } | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
227 st->print_cr("Total " INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13), |
0 | 228 total, totalw * HeapWordSize); |
229 } | |
230 | |
7956 | 231 #define MAKE_COL_NAME(field, name, help) #name, |
232 #define MAKE_COL_HELP(field, name, help) help, | |
233 | |
234 static const char *name_table[] = { | |
235 HEAP_INSPECTION_COLUMNS_DO(MAKE_COL_NAME) | |
236 }; | |
237 | |
238 static const char *help_table[] = { | |
239 HEAP_INSPECTION_COLUMNS_DO(MAKE_COL_HELP) | |
240 }; | |
241 | |
242 bool KlassInfoHisto::is_selected(const char *col_name) { | |
243 if (_selected_columns == NULL) { | |
244 return true; | |
245 } | |
246 if (strcmp(_selected_columns, col_name) == 0) { | |
247 return true; | |
248 } | |
249 | |
250 const char *start = strstr(_selected_columns, col_name); | |
251 if (start == NULL) { | |
252 return false; | |
253 } | |
254 | |
255 // The following must be true, because _selected_columns != col_name | |
256 if (start > _selected_columns && start[-1] != ',') { | |
257 return false; | |
258 } | |
259 char x = start[strlen(col_name)]; | |
260 if (x != ',' && x != '\0') { | |
261 return false; | |
262 } | |
263 | |
264 return true; | |
265 } | |
266 | |
267 void KlassInfoHisto::print_title(outputStream* st, bool csv_format, | |
268 bool selected[], int width_table[], | |
269 const char *name_table[]) { | |
270 if (csv_format) { | |
271 st->print("Index,Super"); | |
272 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
273 if (selected[c]) {st->print(",%s", name_table[c]);} | |
274 } | |
275 st->print(",ClassName"); | |
276 } else { | |
277 st->print("Index Super"); | |
278 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
279 if (selected[c]) {st->print(str_fmt(width_table[c]), name_table[c]);} | |
280 } | |
281 st->print(" ClassName"); | |
282 } | |
283 | |
284 if (is_selected("ClassLoader")) { | |
285 st->print(",ClassLoader"); | |
286 } | |
287 st->cr(); | |
288 } | |
289 | |
290 void KlassInfoHisto::print_class_stats(outputStream* st, | |
291 bool csv_format, const char *columns) { | |
292 ResourceMark rm; | |
293 KlassSizeStats sz, sz_sum; | |
294 int i; | |
295 julong *col_table = (julong*)(&sz); | |
296 julong *colsum_table = (julong*)(&sz_sum); | |
297 int width_table[KlassSizeStats::_num_columns]; | |
298 bool selected[KlassSizeStats::_num_columns]; | |
299 | |
300 _selected_columns = columns; | |
301 | |
302 memset(&sz_sum, 0, sizeof(sz_sum)); | |
303 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
304 selected[c] = is_selected(name_table[c]); | |
305 } | |
306 | |
307 for(i=0; i < elements()->length(); i++) { | |
308 elements()->at(i)->set_index(i+1); | |
309 } | |
310 | |
311 for (int pass=1; pass<=2; pass++) { | |
312 if (pass == 2) { | |
313 print_title(st, csv_format, selected, width_table, name_table); | |
314 } | |
315 for(i=0; i < elements()->length(); i++) { | |
316 KlassInfoEntry* e = (KlassInfoEntry*)elements()->at(i); | |
317 const Klass* k = e->klass(); | |
318 | |
319 memset(&sz, 0, sizeof(sz)); | |
320 sz._inst_count = e->count(); | |
321 sz._inst_bytes = HeapWordSize * e->words(); | |
322 k->collect_statistics(&sz); | |
323 sz._total_bytes = sz._ro_bytes + sz._rw_bytes; | |
324 | |
325 if (pass == 1) { | |
326 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
327 colsum_table[c] += col_table[c]; | |
328 } | |
329 } else { | |
330 int super_index = -1; | |
331 if (k->oop_is_instance()) { | |
332 Klass* super = ((InstanceKlass*)k)->java_super(); | |
333 if (super) { | |
334 KlassInfoEntry* super_e = _cit->lookup(super); | |
335 if (super_e) { | |
336 super_index = super_e->index(); | |
337 } | |
338 } | |
339 } | |
340 | |
341 if (csv_format) { | |
342 st->print("%d,%d", e->index(), super_index); | |
343 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
344 if (selected[c]) {st->print("," JULONG_FORMAT, col_table[c]);} | |
345 } | |
346 st->print(",%s",e->name()); | |
347 } else { | |
348 st->print("%5d %5d", e->index(), super_index); | |
349 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
350 if (selected[c]) {print_julong(st, width_table[c], col_table[c]);} | |
351 } | |
352 st->print(" %s", e->name()); | |
353 } | |
354 if (is_selected("ClassLoader")) { | |
355 ClassLoaderData* loader_data = k->class_loader_data(); | |
356 st->print(","); | |
357 loader_data->print_value_on(st); | |
358 } | |
359 st->cr(); | |
360 } | |
361 } | |
362 | |
363 if (pass == 1) { | |
364 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
365 width_table[c] = col_width(colsum_table[c], name_table[c]); | |
366 } | |
367 } | |
368 } | |
369 | |
370 sz_sum._inst_size = 0; | |
371 | |
372 if (csv_format) { | |
373 st->print(","); | |
374 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
375 if (selected[c]) {st->print("," JULONG_FORMAT, colsum_table[c]);} | |
376 } | |
377 } else { | |
378 st->print(" "); | |
379 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
380 if (selected[c]) {print_julong(st, width_table[c], colsum_table[c]);} | |
381 } | |
382 st->print(" Total"); | |
383 if (sz_sum._total_bytes > 0) { | |
384 st->cr(); | |
385 st->print(" "); | |
386 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
387 if (selected[c]) { | |
388 switch (c) { | |
389 case KlassSizeStats::_index_inst_size: | |
390 case KlassSizeStats::_index_inst_count: | |
391 case KlassSizeStats::_index_method_count: | |
392 st->print(str_fmt(width_table[c]), "-"); | |
393 break; | |
394 default: | |
395 { | |
396 double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes; | |
397 st->print(perc_fmt(width_table[c]), perc); | |
398 } | |
399 } | |
400 } | |
401 } | |
402 } | |
403 } | |
404 st->cr(); | |
405 | |
406 if (!csv_format) { | |
407 print_title(st, csv_format, selected, width_table, name_table); | |
408 } | |
409 } | |
410 | |
411 julong KlassInfoHisto::annotations_bytes(Array<AnnotationArray*>* p) const { | |
412 julong bytes = 0; | |
413 if (p != NULL) { | |
414 for (int i = 0; i < p->length(); i++) { | |
415 bytes += count_bytes_array(p->at(i)); | |
416 } | |
417 bytes += count_bytes_array(p); | |
418 } | |
419 return bytes; | |
420 } | |
421 | |
422 void KlassInfoHisto::print_histo_on(outputStream* st, bool print_stats, | |
423 bool csv_format, const char *columns) { | |
424 if (print_stats) { | |
425 print_class_stats(st, csv_format, columns); | |
426 } else { | |
427 st->print_cr("%s",title()); | |
428 print_elements(st); | |
429 } | |
0 | 430 } |
431 | |
432 class HistoClosure : public KlassInfoClosure { | |
433 private: | |
434 KlassInfoHisto* _cih; | |
435 public: | |
436 HistoClosure(KlassInfoHisto* cih) : _cih(cih) {} | |
437 | |
438 void do_cinfo(KlassInfoEntry* cie) { | |
439 _cih->add(cie); | |
440 } | |
441 }; | |
442 | |
443 class RecordInstanceClosure : public ObjectClosure { | |
444 private: | |
445 KlassInfoTable* _cit; | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
446 size_t _missed_count; |
0 | 447 public: |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
448 RecordInstanceClosure(KlassInfoTable* cit) : |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
449 _cit(cit), _missed_count(0) {} |
0 | 450 |
451 void do_object(oop obj) { | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
452 if (!_cit->record_instance(obj)) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
453 _missed_count++; |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
454 } |
0 | 455 } |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
456 |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
457 size_t missed_count() { return _missed_count; } |
0 | 458 }; |
459 | |
615
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
517
diff
changeset
|
460 void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) { |
0 | 461 ResourceMark rm; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
462 // Get some random number for ref (the hash key) |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
463 HeapWord* ref = (HeapWord*) Universe::boolArrayKlassObj(); |
0 | 464 CollectedHeap* heap = Universe::heap(); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
11
diff
changeset
|
465 bool is_shared_heap = false; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
466 |
7956 | 467 if (_print_help) { |
468 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
469 st->print("%s:\n\t", name_table[c]); | |
470 const int max_col = 60; | |
471 int col = 0; | |
472 for (const char *p = help_table[c]; *p; p++,col++) { | |
473 if (col >= max_col && *p == ' ') { | |
474 st->print("\n\t"); | |
475 col = 0; | |
476 } else { | |
477 st->print("%c", *p); | |
478 } | |
479 } | |
480 st->print_cr(".\n"); | |
481 } | |
482 return; | |
483 } | |
484 | |
0 | 485 // Collect klass instance info |
7956 | 486 KlassInfoTable cit(KlassInfoTable::cit_size, ref, _print_class_stats); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
487 if (!cit.allocation_failed()) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
488 // Iterate over objects in the heap |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
489 RecordInstanceClosure ric(&cit); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
490 Universe::heap()->object_iterate(&ric); |
0 | 491 |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
492 // Report if certain classes are not counted because of |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
493 // running out of C-heap for the histogram. |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
494 size_t missed_count = ric.missed_count(); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
495 if (missed_count != 0) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
496 st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
497 " total instances in data below", |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
498 missed_count); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
499 } |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
500 // Sort and print klass instance info |
7956 | 501 const char *title = "\n" |
502 " num #instances #bytes class name\n" | |
503 "----------------------------------------------"; | |
504 KlassInfoHisto histo(&cit, title, KlassInfoHisto::histo_initial_size); | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
505 HistoClosure hc(&histo); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
506 cit.iterate(&hc); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
507 histo.sort(); |
7956 | 508 histo.print_histo_on(st, _print_class_stats, _csv_format, _columns); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
509 } else { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
510 st->print_cr("WARNING: Ran out of C-heap; histogram not generated"); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
511 } |
0 | 512 st->flush(); |
513 | |
615
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
517
diff
changeset
|
514 if (need_prologue && is_shared_heap) { |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
11
diff
changeset
|
515 SharedHeap* sh = (SharedHeap*)heap; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
11
diff
changeset
|
516 sh->gc_epilogue(false /* !full */); // release all acquired locks, etc. |
0 | 517 } |
518 } | |
519 | |
520 class FindInstanceClosure : public ObjectClosure { | |
521 private: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
522 Klass* _klass; |
0 | 523 GrowableArray<oop>* _result; |
524 | |
525 public: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
526 FindInstanceClosure(Klass* k, GrowableArray<oop>* result) : _klass(k), _result(result) {}; |
0 | 527 |
528 void do_object(oop obj) { | |
529 if (obj->is_a(_klass)) { | |
530 _result->append(obj); | |
531 } | |
532 } | |
533 }; | |
534 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
535 void HeapInspection::find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) { |
0 | 536 assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped"); |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
628
diff
changeset
|
537 assert(Heap_lock->is_locked(), "should have the Heap_lock"); |
0 | 538 |
539 // Ensure that the heap is parsable | |
540 Universe::heap()->ensure_parsability(false); // no need to retire TALBs | |
541 | |
542 // Iterate over objects in the heap | |
543 FindInstanceClosure fic(k, result); | |
517
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
356
diff
changeset
|
544 // If this operation encounters a bad object when using CMS, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
545 // consider using safe_object_iterate() which avoids metadata |
517
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
356
diff
changeset
|
546 // objects that may contain bad references. |
0 | 547 Universe::heap()->object_iterate(&fic); |
548 } |