Mercurial > hg > graal-jvmci-8
annotate src/share/vm/memory/heapInspection.cpp @ 1716:be3f9c242c9d
6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode.
Reviewed-by: chrisphi, johnc, poonam
author | ysr |
---|---|
date | Mon, 16 Aug 2010 15:58:42 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
2 * Copyright (c) 2002, 2009, 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 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_heapInspection.cpp.incl" | |
27 | |
28 // HeapInspection | |
29 | |
30 int KlassInfoEntry::compare(KlassInfoEntry* e1, KlassInfoEntry* e2) { | |
31 if(e1->_instance_words > e2->_instance_words) { | |
32 return -1; | |
33 } else if(e1->_instance_words < e2->_instance_words) { | |
34 return 1; | |
35 } | |
36 return 0; | |
37 } | |
38 | |
39 void KlassInfoEntry::print_on(outputStream* st) const { | |
40 ResourceMark rm; | |
41 const char* name;; | |
42 if (_klass->klass_part()->name() != NULL) { | |
43 name = _klass->klass_part()->external_name(); | |
44 } else { | |
45 if (_klass == Universe::klassKlassObj()) name = "<klassKlass>"; else | |
46 if (_klass == Universe::arrayKlassKlassObj()) name = "<arrayKlassKlass>"; else | |
47 if (_klass == Universe::objArrayKlassKlassObj()) name = "<objArrayKlassKlass>"; else | |
48 if (_klass == Universe::instanceKlassKlassObj()) name = "<instanceKlassKlass>"; else | |
49 if (_klass == Universe::typeArrayKlassKlassObj()) name = "<typeArrayKlassKlass>"; else | |
50 if (_klass == Universe::symbolKlassObj()) name = "<symbolKlass>"; else | |
51 if (_klass == Universe::boolArrayKlassObj()) name = "<boolArrayKlass>"; else | |
52 if (_klass == Universe::charArrayKlassObj()) name = "<charArrayKlass>"; else | |
53 if (_klass == Universe::singleArrayKlassObj()) name = "<singleArrayKlass>"; else | |
54 if (_klass == Universe::doubleArrayKlassObj()) name = "<doubleArrayKlass>"; else | |
55 if (_klass == Universe::byteArrayKlassObj()) name = "<byteArrayKlass>"; else | |
56 if (_klass == Universe::shortArrayKlassObj()) name = "<shortArrayKlass>"; else | |
57 if (_klass == Universe::intArrayKlassObj()) name = "<intArrayKlass>"; else | |
58 if (_klass == Universe::longArrayKlassObj()) name = "<longArrayKlass>"; else | |
59 if (_klass == Universe::methodKlassObj()) name = "<methodKlass>"; else | |
60 if (_klass == Universe::constMethodKlassObj()) name = "<constMethodKlass>"; else | |
61 if (_klass == Universe::methodDataKlassObj()) name = "<methodDataKlass>"; else | |
62 if (_klass == Universe::constantPoolKlassObj()) name = "<constantPoolKlass>"; else | |
63 if (_klass == Universe::constantPoolCacheKlassObj()) name = "<constantPoolCacheKlass>"; else | |
64 if (_klass == Universe::compiledICHolderKlassObj()) name = "<compiledICHolderKlass>"; else | |
65 name = "<no name>"; | |
66 } | |
67 // 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
|
68 st->print_cr(INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13) " %s", |
0 | 69 (jlong) _instance_count, |
70 (julong) _instance_words * HeapWordSize, | |
71 name); | |
72 } | |
73 | |
74 KlassInfoEntry* KlassInfoBucket::lookup(const klassOop k) { | |
75 KlassInfoEntry* elt = _list; | |
76 while (elt != NULL) { | |
77 if (elt->is_equal(k)) { | |
78 return elt; | |
79 } | |
80 elt = elt->next(); | |
81 } | |
82 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
|
83 // 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
|
84 if (elt != NULL) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
85 set_list(elt); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
86 } |
0 | 87 return elt; |
88 } | |
89 | |
90 void KlassInfoBucket::iterate(KlassInfoClosure* cic) { | |
91 KlassInfoEntry* elt = _list; | |
92 while (elt != NULL) { | |
93 cic->do_cinfo(elt); | |
94 elt = elt->next(); | |
95 } | |
96 } | |
97 | |
98 void KlassInfoBucket::empty() { | |
99 KlassInfoEntry* elt = _list; | |
100 _list = NULL; | |
101 while (elt != NULL) { | |
102 KlassInfoEntry* next = elt->next(); | |
103 delete elt; | |
104 elt = next; | |
105 } | |
106 } | |
107 | |
108 KlassInfoTable::KlassInfoTable(int size, HeapWord* ref) { | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
109 _size = 0; |
0 | 110 _ref = ref; |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
111 _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
112 if (_buckets != NULL) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
113 _size = size; |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
114 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
|
115 _buckets[index].initialize(); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
116 } |
0 | 117 } |
118 } | |
119 | |
120 KlassInfoTable::~KlassInfoTable() { | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
121 if (_buckets != NULL) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
122 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
|
123 _buckets[index].empty(); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
124 } |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
125 FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
126 _size = 0; |
0 | 127 } |
128 } | |
129 | |
130 uint KlassInfoTable::hash(klassOop p) { | |
131 assert(Universe::heap()->is_in_permanent((HeapWord*)p), "all klasses in permgen"); | |
132 return (uint)(((uintptr_t)p - (uintptr_t)_ref) >> 2); | |
133 } | |
134 | |
135 KlassInfoEntry* KlassInfoTable::lookup(const klassOop k) { | |
136 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
|
137 assert(_buckets != NULL, "Allocation failure should have been caught"); |
0 | 138 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
|
139 // 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
|
140 // 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
|
141 assert(e == NULL || k == e->klass(), "must be equal"); |
0 | 142 return e; |
143 } | |
144 | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
145 // 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
|
146 // 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
|
147 bool KlassInfoTable::record_instance(const oop obj) { |
0 | 148 klassOop k = obj->klass(); |
149 KlassInfoEntry* elt = lookup(k); | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
150 // 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
|
151 // 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
|
152 if (elt != NULL) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
153 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
|
154 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
|
155 return true; |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
156 } else { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
157 return false; |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
158 } |
0 | 159 } |
160 | |
161 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
|
162 assert(_size == 0 || _buckets != NULL, "Allocation failure should have been caught"); |
0 | 163 for (int index = 0; index < _size; index++) { |
164 _buckets[index].iterate(cic); | |
165 } | |
166 } | |
167 | |
168 int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) { | |
169 return (*e1)->compare(*e1,*e2); | |
170 } | |
171 | |
172 KlassInfoHisto::KlassInfoHisto(const char* title, int estimatedCount) : | |
173 _title(title) { | |
174 _elements = new (ResourceObj::C_HEAP) GrowableArray<KlassInfoEntry*>(estimatedCount,true); | |
175 } | |
176 | |
177 KlassInfoHisto::~KlassInfoHisto() { | |
178 delete _elements; | |
179 } | |
180 | |
181 void KlassInfoHisto::add(KlassInfoEntry* cie) { | |
182 elements()->append(cie); | |
183 } | |
184 | |
185 void KlassInfoHisto::sort() { | |
186 elements()->sort(KlassInfoHisto::sort_helper); | |
187 } | |
188 | |
189 void KlassInfoHisto::print_elements(outputStream* st) const { | |
190 // simplify the formatting (ILP32 vs LP64) - store the sum in 64-bit | |
191 jlong total = 0; | |
192 julong totalw = 0; | |
193 for(int i=0; i < elements()->length(); i++) { | |
194 st->print("%4d: ", i+1); | |
195 elements()->at(i)->print_on(st); | |
196 total += elements()->at(i)->count(); | |
197 totalw += elements()->at(i)->words(); | |
198 } | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
199 st->print_cr("Total " INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13), |
0 | 200 total, totalw * HeapWordSize); |
201 } | |
202 | |
203 void KlassInfoHisto::print_on(outputStream* st) const { | |
204 st->print_cr("%s",title()); | |
205 print_elements(st); | |
206 } | |
207 | |
208 class HistoClosure : public KlassInfoClosure { | |
209 private: | |
210 KlassInfoHisto* _cih; | |
211 public: | |
212 HistoClosure(KlassInfoHisto* cih) : _cih(cih) {} | |
213 | |
214 void do_cinfo(KlassInfoEntry* cie) { | |
215 _cih->add(cie); | |
216 } | |
217 }; | |
218 | |
219 class RecordInstanceClosure : public ObjectClosure { | |
220 private: | |
221 KlassInfoTable* _cit; | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
222 size_t _missed_count; |
0 | 223 public: |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
224 RecordInstanceClosure(KlassInfoTable* cit) : |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
225 _cit(cit), _missed_count(0) {} |
0 | 226 |
227 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
|
228 if (!_cit->record_instance(obj)) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
229 _missed_count++; |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
230 } |
0 | 231 } |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
232 |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
233 size_t missed_count() { return _missed_count; } |
0 | 234 }; |
235 | |
615
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
517
diff
changeset
|
236 void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) { |
0 | 237 ResourceMark rm; |
238 HeapWord* ref; | |
239 | |
240 CollectedHeap* heap = Universe::heap(); | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
11
diff
changeset
|
241 bool is_shared_heap = false; |
0 | 242 switch (heap->kind()) { |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
11
diff
changeset
|
243 case CollectedHeap::G1CollectedHeap: |
0 | 244 case CollectedHeap::GenCollectedHeap: { |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
11
diff
changeset
|
245 is_shared_heap = true; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
11
diff
changeset
|
246 SharedHeap* sh = (SharedHeap*)heap; |
615
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
517
diff
changeset
|
247 if (need_prologue) { |
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
517
diff
changeset
|
248 sh->gc_prologue(false /* !full */); // get any necessary locks, etc. |
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
517
diff
changeset
|
249 } |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
11
diff
changeset
|
250 ref = sh->perm_gen()->used_region().start(); |
0 | 251 break; |
252 } | |
253 #ifndef SERIALGC | |
254 case CollectedHeap::ParallelScavengeHeap: { | |
255 ParallelScavengeHeap* psh = (ParallelScavengeHeap*)heap; | |
256 ref = psh->perm_gen()->object_space()->used_region().start(); | |
257 break; | |
258 } | |
259 #endif // SERIALGC | |
260 default: | |
261 ShouldNotReachHere(); // Unexpected heap kind for this op | |
262 } | |
263 // Collect klass instance info | |
264 KlassInfoTable cit(KlassInfoTable::cit_size, ref); | |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
265 if (!cit.allocation_failed()) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
266 // 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
|
267 RecordInstanceClosure ric(&cit); |
517
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
356
diff
changeset
|
268 // If this operation encounters a bad object when using CMS, |
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
356
diff
changeset
|
269 // consider using safe_object_iterate() which avoids perm gen |
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
356
diff
changeset
|
270 // objects that may contain bad references. |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
271 Universe::heap()->object_iterate(&ric); |
0 | 272 |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
273 // 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
|
274 // 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
|
275 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
|
276 if (missed_count != 0) { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
277 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
|
278 " total instances in data below", |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
279 missed_count); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
280 } |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
281 // Sort and print klass instance info |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
282 KlassInfoHisto histo("\n" |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
283 " num #instances #bytes class name\n" |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
284 "----------------------------------------------", |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
285 KlassInfoHisto::histo_initial_size); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
286 HistoClosure hc(&histo); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
287 cit.iterate(&hc); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
288 histo.sort(); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
289 histo.print_on(st); |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
290 } else { |
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
291 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
|
292 } |
0 | 293 st->flush(); |
294 | |
615
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
517
diff
changeset
|
295 if (need_prologue && is_shared_heap) { |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
11
diff
changeset
|
296 SharedHeap* sh = (SharedHeap*)heap; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
11
diff
changeset
|
297 sh->gc_epilogue(false /* !full */); // release all acquired locks, etc. |
0 | 298 } |
299 } | |
300 | |
301 class FindInstanceClosure : public ObjectClosure { | |
302 private: | |
303 klassOop _klass; | |
304 GrowableArray<oop>* _result; | |
305 | |
306 public: | |
307 FindInstanceClosure(klassOop k, GrowableArray<oop>* result) : _klass(k), _result(result) {}; | |
308 | |
309 void do_object(oop obj) { | |
310 if (obj->is_a(_klass)) { | |
311 _result->append(obj); | |
312 } | |
313 } | |
314 }; | |
315 | |
316 void HeapInspection::find_instances_at_safepoint(klassOop k, GrowableArray<oop>* result) { | |
317 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
|
318 assert(Heap_lock->is_locked(), "should have the Heap_lock"); |
0 | 319 |
320 // Ensure that the heap is parsable | |
321 Universe::heap()->ensure_parsability(false); // no need to retire TALBs | |
322 | |
323 // Iterate over objects in the heap | |
324 FindInstanceClosure fic(k, result); | |
517
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
356
diff
changeset
|
325 // If this operation encounters a bad object when using CMS, |
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
356
diff
changeset
|
326 // consider using safe_object_iterate() which avoids perm gen |
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
356
diff
changeset
|
327 // objects that may contain bad references. |
0 | 328 Universe::heap()->object_iterate(&fic); |
329 } |