Mercurial > hg > truffle
annotate src/share/vm/memory/heapInspection.cpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | 833b0f92429a |
children |
rev | line source |
---|---|
0 | 1 /* |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
11034
diff
changeset
|
2 * Copyright (c) 2002, 2014, 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 |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
11034
diff
changeset
|
38 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
11034
diff
changeset
|
39 |
0 | 40 // HeapInspection |
41 | |
42 int KlassInfoEntry::compare(KlassInfoEntry* e1, KlassInfoEntry* e2) { | |
43 if(e1->_instance_words > e2->_instance_words) { | |
44 return -1; | |
45 } else if(e1->_instance_words < e2->_instance_words) { | |
46 return 1; | |
47 } | |
7956 | 48 // Sort alphabetically, note 'Z' < '[' < 'a', but it's better to group |
49 // the array classes before all the instance classes. | |
50 ResourceMark rm; | |
51 const char* name1 = e1->klass()->external_name(); | |
52 const char* name2 = e2->klass()->external_name(); | |
53 bool d1 = (name1[0] == '['); | |
54 bool d2 = (name2[0] == '['); | |
55 if (d1 && !d2) { | |
56 return -1; | |
57 } else if (d2 && !d1) { | |
58 return 1; | |
59 } else { | |
60 return strcmp(name1, name2); | |
61 } | |
0 | 62 } |
63 | |
7956 | 64 const char* KlassInfoEntry::name() const { |
65 const char* name; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
66 if (_klass->name() != NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
67 name = _klass->external_name(); |
0 | 68 } else { |
69 if (_klass == Universe::boolArrayKlassObj()) name = "<boolArrayKlass>"; else | |
70 if (_klass == Universe::charArrayKlassObj()) name = "<charArrayKlass>"; else | |
71 if (_klass == Universe::singleArrayKlassObj()) name = "<singleArrayKlass>"; else | |
72 if (_klass == Universe::doubleArrayKlassObj()) name = "<doubleArrayKlass>"; else | |
73 if (_klass == Universe::byteArrayKlassObj()) name = "<byteArrayKlass>"; else | |
74 if (_klass == Universe::shortArrayKlassObj()) name = "<shortArrayKlass>"; else | |
75 if (_klass == Universe::intArrayKlassObj()) name = "<intArrayKlass>"; else | |
76 if (_klass == Universe::longArrayKlassObj()) name = "<longArrayKlass>"; else | |
77 name = "<no name>"; | |
78 } | |
7956 | 79 return name; |
80 } | |
81 | |
82 void KlassInfoEntry::print_on(outputStream* st) const { | |
83 ResourceMark rm; | |
84 | |
0 | 85 // 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
|
86 st->print_cr(INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13) " %s", |
0 | 87 (jlong) _instance_count, |
88 (julong) _instance_words * HeapWordSize, | |
7956 | 89 name()); |
0 | 90 } |
91 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
92 KlassInfoEntry* KlassInfoBucket::lookup(Klass* const k) { |
0 | 93 KlassInfoEntry* elt = _list; |
94 while (elt != NULL) { | |
95 if (elt->is_equal(k)) { | |
96 return elt; | |
97 } | |
98 elt = elt->next(); | |
99 } | |
10405 | 100 elt = new (std::nothrow) KlassInfoEntry(k, list()); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
101 // 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
|
102 if (elt != NULL) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
103 set_list(elt); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
104 } |
0 | 105 return elt; |
106 } | |
107 | |
108 void KlassInfoBucket::iterate(KlassInfoClosure* cic) { | |
109 KlassInfoEntry* elt = _list; | |
110 while (elt != NULL) { | |
111 cic->do_cinfo(elt); | |
112 elt = elt->next(); | |
113 } | |
114 } | |
115 | |
116 void KlassInfoBucket::empty() { | |
117 KlassInfoEntry* elt = _list; | |
118 _list = NULL; | |
119 while (elt != NULL) { | |
120 KlassInfoEntry* next = elt->next(); | |
121 delete elt; | |
122 elt = next; | |
123 } | |
124 } | |
125 | |
7956 | 126 void KlassInfoTable::AllClassesFinder::do_klass(Klass* k) { |
127 // This has the SIDE EFFECT of creating a KlassInfoEntry | |
128 // for <k>, if one doesn't exist yet. | |
129 _table->lookup(k); | |
130 } | |
131 | |
10405 | 132 KlassInfoTable::KlassInfoTable(bool need_class_stats) { |
133 _size_of_instances_in_words = 0; | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
134 _size = 0; |
10405 | 135 _ref = (HeapWord*) Universe::boolArrayKlassObj(); |
136 _buckets = | |
137 (KlassInfoBucket*) AllocateHeap(sizeof(KlassInfoBucket) * _num_buckets, | |
20360 | 138 mtInternal, CURRENT_PC, AllocFailStrategy::RETURN_NULL); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
139 if (_buckets != NULL) { |
10405 | 140 _size = _num_buckets; |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
141 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
|
142 _buckets[index].initialize(); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
143 } |
7956 | 144 if (need_class_stats) { |
145 AllClassesFinder finder(this); | |
146 ClassLoaderDataGraph::classes_do(&finder); | |
147 } | |
0 | 148 } |
149 } | |
150 | |
151 KlassInfoTable::~KlassInfoTable() { | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
152 if (_buckets != NULL) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
153 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
|
154 _buckets[index].empty(); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
155 } |
6197 | 156 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
|
157 _size = 0; |
0 | 158 } |
159 } | |
160 | |
10265
92ef81e2f571
8003557: NPG: Klass* const k should be const Klass* k.
minqi
parents:
8003
diff
changeset
|
161 uint KlassInfoTable::hash(const Klass* p) { |
0 | 162 return (uint)(((uintptr_t)p - (uintptr_t)_ref) >> 2); |
163 } | |
164 | |
10265
92ef81e2f571
8003557: NPG: Klass* const k should be const Klass* k.
minqi
parents:
8003
diff
changeset
|
165 KlassInfoEntry* KlassInfoTable::lookup(Klass* k) { |
0 | 166 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
|
167 assert(_buckets != NULL, "Allocation failure should have been caught"); |
0 | 168 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
|
169 // 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
|
170 // 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
|
171 assert(e == NULL || k == e->klass(), "must be equal"); |
0 | 172 return e; |
173 } | |
174 | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
175 // 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
|
176 // 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
|
177 bool KlassInfoTable::record_instance(const oop obj) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
178 Klass* k = obj->klass(); |
0 | 179 KlassInfoEntry* elt = lookup(k); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
180 // 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
|
181 // 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
|
182 if (elt != NULL) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
183 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
|
184 elt->set_words(elt->words() + obj->size()); |
10405 | 185 _size_of_instances_in_words += obj->size(); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
186 return true; |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
187 } else { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
188 return false; |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
189 } |
0 | 190 } |
191 | |
192 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
|
193 assert(_size == 0 || _buckets != NULL, "Allocation failure should have been caught"); |
0 | 194 for (int index = 0; index < _size; index++) { |
195 _buckets[index].iterate(cic); | |
196 } | |
197 } | |
198 | |
10405 | 199 size_t KlassInfoTable::size_of_instances_in_words() const { |
200 return _size_of_instances_in_words; | |
201 } | |
202 | |
0 | 203 int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) { |
204 return (*e1)->compare(*e1,*e2); | |
205 } | |
206 | |
10405 | 207 KlassInfoHisto::KlassInfoHisto(KlassInfoTable* cit, const char* title) : |
7956 | 208 _cit(cit), |
0 | 209 _title(title) { |
10405 | 210 _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(_histo_initial_size, true); |
0 | 211 } |
212 | |
213 KlassInfoHisto::~KlassInfoHisto() { | |
214 delete _elements; | |
215 } | |
216 | |
217 void KlassInfoHisto::add(KlassInfoEntry* cie) { | |
218 elements()->append(cie); | |
219 } | |
220 | |
221 void KlassInfoHisto::sort() { | |
222 elements()->sort(KlassInfoHisto::sort_helper); | |
223 } | |
224 | |
225 void KlassInfoHisto::print_elements(outputStream* st) const { | |
226 // simplify the formatting (ILP32 vs LP64) - store the sum in 64-bit | |
227 jlong total = 0; | |
228 julong totalw = 0; | |
229 for(int i=0; i < elements()->length(); i++) { | |
230 st->print("%4d: ", i+1); | |
231 elements()->at(i)->print_on(st); | |
232 total += elements()->at(i)->count(); | |
233 totalw += elements()->at(i)->words(); | |
234 } | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
235 st->print_cr("Total " INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13), |
0 | 236 total, totalw * HeapWordSize); |
237 } | |
238 | |
7956 | 239 #define MAKE_COL_NAME(field, name, help) #name, |
240 #define MAKE_COL_HELP(field, name, help) help, | |
241 | |
242 static const char *name_table[] = { | |
243 HEAP_INSPECTION_COLUMNS_DO(MAKE_COL_NAME) | |
244 }; | |
245 | |
246 static const char *help_table[] = { | |
247 HEAP_INSPECTION_COLUMNS_DO(MAKE_COL_HELP) | |
248 }; | |
249 | |
250 bool KlassInfoHisto::is_selected(const char *col_name) { | |
251 if (_selected_columns == NULL) { | |
252 return true; | |
253 } | |
254 if (strcmp(_selected_columns, col_name) == 0) { | |
255 return true; | |
256 } | |
257 | |
258 const char *start = strstr(_selected_columns, col_name); | |
259 if (start == NULL) { | |
260 return false; | |
261 } | |
262 | |
263 // The following must be true, because _selected_columns != col_name | |
264 if (start > _selected_columns && start[-1] != ',') { | |
265 return false; | |
266 } | |
267 char x = start[strlen(col_name)]; | |
268 if (x != ',' && x != '\0') { | |
269 return false; | |
270 } | |
271 | |
272 return true; | |
273 } | |
274 | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
11034
diff
changeset
|
275 PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL |
7956 | 276 void KlassInfoHisto::print_title(outputStream* st, bool csv_format, |
277 bool selected[], int width_table[], | |
278 const char *name_table[]) { | |
279 if (csv_format) { | |
280 st->print("Index,Super"); | |
281 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
282 if (selected[c]) {st->print(",%s", name_table[c]);} | |
283 } | |
284 st->print(",ClassName"); | |
285 } else { | |
286 st->print("Index Super"); | |
287 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
11034
diff
changeset
|
288 PRAGMA_DIAG_PUSH |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
11034
diff
changeset
|
289 PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL |
7956 | 290 if (selected[c]) {st->print(str_fmt(width_table[c]), name_table[c]);} |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
11034
diff
changeset
|
291 PRAGMA_DIAG_POP |
7956 | 292 } |
293 st->print(" ClassName"); | |
294 } | |
295 | |
296 if (is_selected("ClassLoader")) { | |
297 st->print(",ClassLoader"); | |
298 } | |
299 st->cr(); | |
300 } | |
301 | |
302 void KlassInfoHisto::print_class_stats(outputStream* st, | |
303 bool csv_format, const char *columns) { | |
304 ResourceMark rm; | |
305 KlassSizeStats sz, sz_sum; | |
306 int i; | |
307 julong *col_table = (julong*)(&sz); | |
308 julong *colsum_table = (julong*)(&sz_sum); | |
309 int width_table[KlassSizeStats::_num_columns]; | |
310 bool selected[KlassSizeStats::_num_columns]; | |
311 | |
312 _selected_columns = columns; | |
313 | |
314 memset(&sz_sum, 0, sizeof(sz_sum)); | |
315 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
316 selected[c] = is_selected(name_table[c]); | |
317 } | |
318 | |
319 for(i=0; i < elements()->length(); i++) { | |
320 elements()->at(i)->set_index(i+1); | |
321 } | |
322 | |
323 for (int pass=1; pass<=2; pass++) { | |
324 if (pass == 2) { | |
325 print_title(st, csv_format, selected, width_table, name_table); | |
326 } | |
327 for(i=0; i < elements()->length(); i++) { | |
328 KlassInfoEntry* e = (KlassInfoEntry*)elements()->at(i); | |
329 const Klass* k = e->klass(); | |
330 | |
331 memset(&sz, 0, sizeof(sz)); | |
332 sz._inst_count = e->count(); | |
333 sz._inst_bytes = HeapWordSize * e->words(); | |
334 k->collect_statistics(&sz); | |
335 sz._total_bytes = sz._ro_bytes + sz._rw_bytes; | |
336 | |
337 if (pass == 1) { | |
338 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
339 colsum_table[c] += col_table[c]; | |
340 } | |
341 } else { | |
342 int super_index = -1; | |
343 if (k->oop_is_instance()) { | |
344 Klass* super = ((InstanceKlass*)k)->java_super(); | |
345 if (super) { | |
346 KlassInfoEntry* super_e = _cit->lookup(super); | |
347 if (super_e) { | |
348 super_index = super_e->index(); | |
349 } | |
350 } | |
351 } | |
352 | |
353 if (csv_format) { | |
354 st->print("%d,%d", e->index(), super_index); | |
355 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
356 if (selected[c]) {st->print("," JULONG_FORMAT, col_table[c]);} | |
357 } | |
358 st->print(",%s",e->name()); | |
359 } else { | |
360 st->print("%5d %5d", e->index(), super_index); | |
361 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
362 if (selected[c]) {print_julong(st, width_table[c], col_table[c]);} | |
363 } | |
364 st->print(" %s", e->name()); | |
365 } | |
366 if (is_selected("ClassLoader")) { | |
367 ClassLoaderData* loader_data = k->class_loader_data(); | |
368 st->print(","); | |
369 loader_data->print_value_on(st); | |
370 } | |
371 st->cr(); | |
372 } | |
373 } | |
374 | |
375 if (pass == 1) { | |
376 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
377 width_table[c] = col_width(colsum_table[c], name_table[c]); | |
378 } | |
379 } | |
380 } | |
381 | |
382 sz_sum._inst_size = 0; | |
383 | |
384 if (csv_format) { | |
385 st->print(","); | |
386 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
387 if (selected[c]) {st->print("," JULONG_FORMAT, colsum_table[c]);} | |
388 } | |
389 } else { | |
390 st->print(" "); | |
391 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
392 if (selected[c]) {print_julong(st, width_table[c], colsum_table[c]);} | |
393 } | |
394 st->print(" Total"); | |
395 if (sz_sum._total_bytes > 0) { | |
396 st->cr(); | |
397 st->print(" "); | |
398 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
399 if (selected[c]) { | |
400 switch (c) { | |
401 case KlassSizeStats::_index_inst_size: | |
402 case KlassSizeStats::_index_inst_count: | |
403 case KlassSizeStats::_index_method_count: | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
11034
diff
changeset
|
404 PRAGMA_DIAG_PUSH |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
11034
diff
changeset
|
405 PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL |
7956 | 406 st->print(str_fmt(width_table[c]), "-"); |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
11034
diff
changeset
|
407 PRAGMA_DIAG_POP |
7956 | 408 break; |
409 default: | |
410 { | |
411 double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes; | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
11034
diff
changeset
|
412 PRAGMA_DIAG_PUSH |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
11034
diff
changeset
|
413 PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL |
7956 | 414 st->print(perc_fmt(width_table[c]), perc); |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
11034
diff
changeset
|
415 PRAGMA_DIAG_POP |
7956 | 416 } |
417 } | |
418 } | |
419 } | |
420 } | |
421 } | |
422 st->cr(); | |
423 | |
424 if (!csv_format) { | |
425 print_title(st, csv_format, selected, width_table, name_table); | |
426 } | |
427 } | |
428 | |
429 julong KlassInfoHisto::annotations_bytes(Array<AnnotationArray*>* p) const { | |
430 julong bytes = 0; | |
431 if (p != NULL) { | |
432 for (int i = 0; i < p->length(); i++) { | |
433 bytes += count_bytes_array(p->at(i)); | |
434 } | |
435 bytes += count_bytes_array(p); | |
436 } | |
437 return bytes; | |
438 } | |
439 | |
440 void KlassInfoHisto::print_histo_on(outputStream* st, bool print_stats, | |
441 bool csv_format, const char *columns) { | |
442 if (print_stats) { | |
443 print_class_stats(st, csv_format, columns); | |
444 } else { | |
445 st->print_cr("%s",title()); | |
446 print_elements(st); | |
447 } | |
0 | 448 } |
449 | |
450 class HistoClosure : public KlassInfoClosure { | |
451 private: | |
452 KlassInfoHisto* _cih; | |
453 public: | |
454 HistoClosure(KlassInfoHisto* cih) : _cih(cih) {} | |
455 | |
456 void do_cinfo(KlassInfoEntry* cie) { | |
457 _cih->add(cie); | |
458 } | |
459 }; | |
460 | |
461 class RecordInstanceClosure : public ObjectClosure { | |
462 private: | |
463 KlassInfoTable* _cit; | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
464 size_t _missed_count; |
10405 | 465 BoolObjectClosure* _filter; |
0 | 466 public: |
10405 | 467 RecordInstanceClosure(KlassInfoTable* cit, BoolObjectClosure* filter) : |
468 _cit(cit), _missed_count(0), _filter(filter) {} | |
0 | 469 |
470 void do_object(oop obj) { | |
10405 | 471 if (should_visit(obj)) { |
472 if (!_cit->record_instance(obj)) { | |
473 _missed_count++; | |
474 } | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
475 } |
0 | 476 } |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
477 |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
478 size_t missed_count() { return _missed_count; } |
10405 | 479 |
480 private: | |
481 bool should_visit(oop obj) { | |
482 return _filter == NULL || _filter->do_object_b(obj); | |
483 } | |
0 | 484 }; |
485 | |
10405 | 486 size_t HeapInspection::populate_table(KlassInfoTable* cit, BoolObjectClosure *filter) { |
0 | 487 ResourceMark rm; |
10405 | 488 |
489 RecordInstanceClosure ric(cit, filter); | |
490 Universe::heap()->object_iterate(&ric); | |
491 return ric.missed_count(); | |
492 } | |
493 | |
494 void HeapInspection::heap_inspection(outputStream* st) { | |
495 ResourceMark rm; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
496 |
7956 | 497 if (_print_help) { |
498 for (int c=0; c<KlassSizeStats::_num_columns; c++) { | |
499 st->print("%s:\n\t", name_table[c]); | |
500 const int max_col = 60; | |
501 int col = 0; | |
502 for (const char *p = help_table[c]; *p; p++,col++) { | |
503 if (col >= max_col && *p == ' ') { | |
504 st->print("\n\t"); | |
505 col = 0; | |
506 } else { | |
507 st->print("%c", *p); | |
508 } | |
509 } | |
510 st->print_cr(".\n"); | |
511 } | |
512 return; | |
513 } | |
514 | |
10405 | 515 KlassInfoTable cit(_print_class_stats); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
516 if (!cit.allocation_failed()) { |
10405 | 517 size_t missed_count = populate_table(&cit); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
518 if (missed_count != 0) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
519 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
|
520 " total instances in data below", |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
521 missed_count); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
522 } |
10405 | 523 |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
524 // Sort and print klass instance info |
7956 | 525 const char *title = "\n" |
526 " num #instances #bytes class name\n" | |
527 "----------------------------------------------"; | |
10405 | 528 KlassInfoHisto histo(&cit, title); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
529 HistoClosure hc(&histo); |
10405 | 530 |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
531 cit.iterate(&hc); |
10405 | 532 |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
533 histo.sort(); |
7956 | 534 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
|
535 } else { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
536 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
|
537 } |
0 | 538 st->flush(); |
539 } | |
540 | |
541 class FindInstanceClosure : public ObjectClosure { | |
542 private: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
543 Klass* _klass; |
0 | 544 GrowableArray<oop>* _result; |
545 | |
546 public: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
547 FindInstanceClosure(Klass* k, GrowableArray<oop>* result) : _klass(k), _result(result) {}; |
0 | 548 |
549 void do_object(oop obj) { | |
550 if (obj->is_a(_klass)) { | |
551 _result->append(obj); | |
552 } | |
553 } | |
554 }; | |
555 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
556 void HeapInspection::find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) { |
0 | 557 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
|
558 assert(Heap_lock->is_locked(), "should have the Heap_lock"); |
0 | 559 |
560 // Ensure that the heap is parsable | |
561 Universe::heap()->ensure_parsability(false); // no need to retire TALBs | |
562 | |
563 // Iterate over objects in the heap | |
564 FindInstanceClosure fic(k, result); | |
517
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
356
diff
changeset
|
565 // 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
|
566 // consider using safe_object_iterate() which avoids metadata |
517
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
356
diff
changeset
|
567 // objects that may contain bad references. |
0 | 568 Universe::heap()->object_iterate(&fic); |
569 } |