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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
7956
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
2 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
25 #include "precompiled.hpp"
7956
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
26 #include "classfile/classLoaderData.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27 #include "gc_interface/collectedHeap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "memory/genCollectedHeap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "memory/heapInspection.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30 #include "memory/resourceArea.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
31 #include "runtime/os.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
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
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // HeapInspection
a61af66fc99e Initial load
duke
parents:
diff changeset
39
a61af66fc99e Initial load
duke
parents:
diff changeset
40 int KlassInfoEntry::compare(KlassInfoEntry* e1, KlassInfoEntry* e2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
41 if(e1->_instance_words > e2->_instance_words) {
a61af66fc99e Initial load
duke
parents:
diff changeset
42 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
43 } else if(e1->_instance_words < e2->_instance_words) {
a61af66fc99e Initial load
duke
parents:
diff changeset
44 return 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 }
7956
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
46 // Sort alphabetically, note 'Z' < '[' < 'a', but it's better to group
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
47 // the array classes before all the instance classes.
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
48 ResourceMark rm;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
49 const char* name1 = e1->klass()->external_name();
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
50 const char* name2 = e2->klass()->external_name();
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
51 bool d1 = (name1[0] == '[');
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
52 bool d2 = (name2[0] == '[');
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
53 if (d1 && !d2) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
54 return -1;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
55 } else if (d2 && !d1) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
56 return 1;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
57 } else {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
58 return strcmp(name1, name2);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
59 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
60 }
a61af66fc99e Initial load
duke
parents:
diff changeset
61
7956
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
62 const char* KlassInfoEntry::name() const {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
66 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
67 if (_klass == Universe::boolArrayKlassObj()) name = "<boolArrayKlass>"; else
a61af66fc99e Initial load
duke
parents:
diff changeset
68 if (_klass == Universe::charArrayKlassObj()) name = "<charArrayKlass>"; else
a61af66fc99e Initial load
duke
parents:
diff changeset
69 if (_klass == Universe::singleArrayKlassObj()) name = "<singleArrayKlass>"; else
a61af66fc99e Initial load
duke
parents:
diff changeset
70 if (_klass == Universe::doubleArrayKlassObj()) name = "<doubleArrayKlass>"; else
a61af66fc99e Initial load
duke
parents:
diff changeset
71 if (_klass == Universe::byteArrayKlassObj()) name = "<byteArrayKlass>"; else
a61af66fc99e Initial load
duke
parents:
diff changeset
72 if (_klass == Universe::shortArrayKlassObj()) name = "<shortArrayKlass>"; else
a61af66fc99e Initial load
duke
parents:
diff changeset
73 if (_klass == Universe::intArrayKlassObj()) name = "<intArrayKlass>"; else
a61af66fc99e Initial load
duke
parents:
diff changeset
74 if (_klass == Universe::longArrayKlassObj()) name = "<longArrayKlass>"; else
a61af66fc99e Initial load
duke
parents:
diff changeset
75 name = "<no name>";
a61af66fc99e Initial load
duke
parents:
diff changeset
76 }
7956
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
77 return name;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
78 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
79
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
80 void KlassInfoEntry::print_on(outputStream* st) const {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
81 ResourceMark rm;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
82
0
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
85 (jlong) _instance_count,
a61af66fc99e Initial load
duke
parents:
diff changeset
86 (julong) _instance_words * HeapWordSize,
7956
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
87 name());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
88 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
91 KlassInfoEntry* elt = _list;
a61af66fc99e Initial load
duke
parents:
diff changeset
92 while (elt != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
93 if (elt->is_equal(k)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
94 return elt;
a61af66fc99e Initial load
duke
parents:
diff changeset
95 }
a61af66fc99e Initial load
duke
parents:
diff changeset
96 elt = elt->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
97 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
103 return elt;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 void KlassInfoBucket::iterate(KlassInfoClosure* cic) {
a61af66fc99e Initial load
duke
parents:
diff changeset
107 KlassInfoEntry* elt = _list;
a61af66fc99e Initial load
duke
parents:
diff changeset
108 while (elt != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 cic->do_cinfo(elt);
a61af66fc99e Initial load
duke
parents:
diff changeset
110 elt = elt->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114 void KlassInfoBucket::empty() {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 KlassInfoEntry* elt = _list;
a61af66fc99e Initial load
duke
parents:
diff changeset
116 _list = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
117 while (elt != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 KlassInfoEntry* next = elt->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
119 delete elt;
a61af66fc99e Initial load
duke
parents:
diff changeset
120 elt = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
123
7956
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
124 void KlassInfoTable::AllClassesFinder::do_klass(Klass* k) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
125 // This has the SIDE EFFECT of creating a KlassInfoEntry
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
126 // for <k>, if one doesn't exist yet.
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
127 _table->lookup(k);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
128 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
129
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
130 KlassInfoTable::KlassInfoTable(int size, HeapWord* ref,
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
133 _ref = ref;
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 2426
diff changeset
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
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
140 if (need_class_stats) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
141 AllClassesFinder finder(this);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
142 ClassLoaderDataGraph::classes_do(&finder);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
143 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
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
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 2426
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
159 return (uint)(((uintptr_t)p - (uintptr_t)_ref) >> 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
169 return e;
a61af66fc99e Initial load
duke
parents:
diff changeset
170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
190 for (int index = 0; index < _size; index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 _buckets[index].iterate(cic);
a61af66fc99e Initial load
duke
parents:
diff changeset
192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
194
a61af66fc99e Initial load
duke
parents:
diff changeset
195 int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 return (*e1)->compare(*e1,*e2);
a61af66fc99e Initial load
duke
parents:
diff changeset
197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
198
7956
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
199 KlassInfoHisto::KlassInfoHisto(KlassInfoTable* cit, const char* title, int estimatedCount) :
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
200 _cit(cit),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
201 _title(title) {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 2426
diff changeset
202 _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(estimatedCount,true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 KlassInfoHisto::~KlassInfoHisto() {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 delete _elements;
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 void KlassInfoHisto::add(KlassInfoEntry* cie) {
a61af66fc99e Initial load
duke
parents:
diff changeset
210 elements()->append(cie);
a61af66fc99e Initial load
duke
parents:
diff changeset
211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 void KlassInfoHisto::sort() {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 elements()->sort(KlassInfoHisto::sort_helper);
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 void KlassInfoHisto::print_elements(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // simplify the formatting (ILP32 vs LP64) - store the sum in 64-bit
a61af66fc99e Initial load
duke
parents:
diff changeset
219 jlong total = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
220 julong totalw = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
221 for(int i=0; i < elements()->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
222 st->print("%4d: ", i+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
223 elements()->at(i)->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
224 total += elements()->at(i)->count();
a61af66fc99e Initial load
duke
parents:
diff changeset
225 totalw += elements()->at(i)->words();
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
228 total, totalw * HeapWordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
230
7956
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
231 #define MAKE_COL_NAME(field, name, help) #name,
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
232 #define MAKE_COL_HELP(field, name, help) help,
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
233
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
234 static const char *name_table[] = {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
235 HEAP_INSPECTION_COLUMNS_DO(MAKE_COL_NAME)
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
236 };
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
237
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
238 static const char *help_table[] = {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
239 HEAP_INSPECTION_COLUMNS_DO(MAKE_COL_HELP)
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
240 };
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
241
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
242 bool KlassInfoHisto::is_selected(const char *col_name) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
243 if (_selected_columns == NULL) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
244 return true;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
245 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
246 if (strcmp(_selected_columns, col_name) == 0) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
247 return true;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
248 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
249
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
250 const char *start = strstr(_selected_columns, col_name);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
251 if (start == NULL) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
252 return false;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
253 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
254
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
255 // The following must be true, because _selected_columns != col_name
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
256 if (start > _selected_columns && start[-1] != ',') {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
257 return false;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
258 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
259 char x = start[strlen(col_name)];
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
260 if (x != ',' && x != '\0') {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
261 return false;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
262 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
263
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
264 return true;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
265 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
266
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
267 void KlassInfoHisto::print_title(outputStream* st, bool csv_format,
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
268 bool selected[], int width_table[],
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
269 const char *name_table[]) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
270 if (csv_format) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
271 st->print("Index,Super");
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
272 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
273 if (selected[c]) {st->print(",%s", name_table[c]);}
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
274 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
275 st->print(",ClassName");
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
276 } else {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
277 st->print("Index Super");
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
278 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
279 if (selected[c]) {st->print(str_fmt(width_table[c]), name_table[c]);}
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
280 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
281 st->print(" ClassName");
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
282 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
283
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
284 if (is_selected("ClassLoader")) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
285 st->print(",ClassLoader");
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
286 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
287 st->cr();
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
288 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
289
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
290 void KlassInfoHisto::print_class_stats(outputStream* st,
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
291 bool csv_format, const char *columns) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
292 ResourceMark rm;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
293 KlassSizeStats sz, sz_sum;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
294 int i;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
295 julong *col_table = (julong*)(&sz);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
296 julong *colsum_table = (julong*)(&sz_sum);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
297 int width_table[KlassSizeStats::_num_columns];
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
298 bool selected[KlassSizeStats::_num_columns];
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
299
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
300 _selected_columns = columns;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
301
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
302 memset(&sz_sum, 0, sizeof(sz_sum));
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
303 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
304 selected[c] = is_selected(name_table[c]);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
305 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
306
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
307 for(i=0; i < elements()->length(); i++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
308 elements()->at(i)->set_index(i+1);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
309 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
310
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
311 for (int pass=1; pass<=2; pass++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
312 if (pass == 2) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
313 print_title(st, csv_format, selected, width_table, name_table);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
314 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
315 for(i=0; i < elements()->length(); i++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
316 KlassInfoEntry* e = (KlassInfoEntry*)elements()->at(i);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
317 const Klass* k = e->klass();
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
318
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
319 memset(&sz, 0, sizeof(sz));
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
320 sz._inst_count = e->count();
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
321 sz._inst_bytes = HeapWordSize * e->words();
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
322 k->collect_statistics(&sz);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
323 sz._total_bytes = sz._ro_bytes + sz._rw_bytes;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
324
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
325 if (pass == 1) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
326 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
327 colsum_table[c] += col_table[c];
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
328 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
329 } else {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
330 int super_index = -1;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
331 if (k->oop_is_instance()) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
332 Klass* super = ((InstanceKlass*)k)->java_super();
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
333 if (super) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
334 KlassInfoEntry* super_e = _cit->lookup(super);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
335 if (super_e) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
336 super_index = super_e->index();
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
337 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
338 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
339 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
340
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
341 if (csv_format) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
342 st->print("%d,%d", e->index(), super_index);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
343 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
344 if (selected[c]) {st->print("," JULONG_FORMAT, col_table[c]);}
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
345 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
346 st->print(",%s",e->name());
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
347 } else {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
348 st->print("%5d %5d", e->index(), super_index);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
349 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
350 if (selected[c]) {print_julong(st, width_table[c], col_table[c]);}
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
351 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
352 st->print(" %s", e->name());
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
353 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
354 if (is_selected("ClassLoader")) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
355 ClassLoaderData* loader_data = k->class_loader_data();
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
356 st->print(",");
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
357 loader_data->print_value_on(st);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
358 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
359 st->cr();
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
360 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
361 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
362
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
363 if (pass == 1) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
364 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
365 width_table[c] = col_width(colsum_table[c], name_table[c]);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
366 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
367 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
368 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
369
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
370 sz_sum._inst_size = 0;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
371
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
372 if (csv_format) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
373 st->print(",");
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
374 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
375 if (selected[c]) {st->print("," JULONG_FORMAT, colsum_table[c]);}
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
376 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
377 } else {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
378 st->print(" ");
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
379 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
380 if (selected[c]) {print_julong(st, width_table[c], colsum_table[c]);}
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
381 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
382 st->print(" Total");
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
383 if (sz_sum._total_bytes > 0) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
384 st->cr();
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
385 st->print(" ");
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
386 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
387 if (selected[c]) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
388 switch (c) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
389 case KlassSizeStats::_index_inst_size:
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
390 case KlassSizeStats::_index_inst_count:
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
391 case KlassSizeStats::_index_method_count:
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
392 st->print(str_fmt(width_table[c]), "-");
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
393 break;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
394 default:
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
395 {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
396 double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
397 st->print(perc_fmt(width_table[c]), perc);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
398 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
399 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
400 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
401 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
402 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
403 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
404 st->cr();
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
405
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
406 if (!csv_format) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
407 print_title(st, csv_format, selected, width_table, name_table);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
408 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
409 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
410
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
411 julong KlassInfoHisto::annotations_bytes(Array<AnnotationArray*>* p) const {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
412 julong bytes = 0;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
413 if (p != NULL) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
414 for (int i = 0; i < p->length(); i++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
415 bytes += count_bytes_array(p->at(i));
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
416 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
417 bytes += count_bytes_array(p);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
418 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
419 return bytes;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
420 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
421
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
422 void KlassInfoHisto::print_histo_on(outputStream* st, bool print_stats,
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
423 bool csv_format, const char *columns) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
424 if (print_stats) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
425 print_class_stats(st, csv_format, columns);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
426 } else {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
427 st->print_cr("%s",title());
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
428 print_elements(st);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
429 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
431
a61af66fc99e Initial load
duke
parents:
diff changeset
432 class HistoClosure : public KlassInfoClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
433 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
434 KlassInfoHisto* _cih;
a61af66fc99e Initial load
duke
parents:
diff changeset
435 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
436 HistoClosure(KlassInfoHisto* cih) : _cih(cih) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
437
a61af66fc99e Initial load
duke
parents:
diff changeset
438 void do_cinfo(KlassInfoEntry* cie) {
a61af66fc99e Initial load
duke
parents:
diff changeset
439 _cih->add(cie);
a61af66fc99e Initial load
duke
parents:
diff changeset
440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
441 };
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443 class RecordInstanceClosure : public ObjectClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
444 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
458 };
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
467 if (_print_help) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
468 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
469 st->print("%s:\n\t", name_table[c]);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
470 const int max_col = 60;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
471 int col = 0;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
472 for (const char *p = help_table[c]; *p; p++,col++) {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
473 if (col >= max_col && *p == ' ') {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
474 st->print("\n\t");
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
475 col = 0;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
476 } else {
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
477 st->print("%c", *p);
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
478 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
479 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
480 st->print_cr(".\n");
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
481 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
482 return;
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
483 }
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
484
0
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // Collect klass instance info
7956
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
501 const char *title = "\n"
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
502 " num #instances #bytes class name\n"
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
503 "----------------------------------------------";
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
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
16fb9f942703 6479360: PrintClassHistogram improvements
acorn
parents: 6725
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
512 st->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
519
a61af66fc99e Initial load
duke
parents:
diff changeset
520 class FindInstanceClosure : public ObjectClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
521 private:
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6197
diff changeset
522 Klass* _klass;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
523 GrowableArray<oop>* _result;
a61af66fc99e Initial load
duke
parents:
diff changeset
524
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
527
a61af66fc99e Initial load
duke
parents:
diff changeset
528 void do_object(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
529 if (obj->is_a(_klass)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
530 _result->append(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
533 };
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
538
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // Ensure that the heap is parsable
a61af66fc99e Initial load
duke
parents:
diff changeset
540 Universe::heap()->ensure_parsability(false); // no need to retire TALBs
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 // Iterate over objects in the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
547 Universe::heap()->object_iterate(&fic);
a61af66fc99e Initial load
duke
parents:
diff changeset
548 }