1 /* 2 * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. 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 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "gc_interface/collectedHeap.hpp" 27 #include "memory/genCollectedHeap.hpp" 28 #include "memory/heapInspection.hpp" 29 #include "memory/resourceArea.hpp" 30 #include "oops/klassOop.hpp" 31 #include "runtime/os.hpp" 32 #include "utilities/globalDefinitions.hpp" 33 #ifndef SERIALGC 34 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" 35 #endif 36 37 // HeapInspection 38 39 int KlassInfoEntry::compare(KlassInfoEntry* e1, KlassInfoEntry* e2) { 40 if(e1->_instance_words > e2->_instance_words) { 41 return -1; 42 } else if(e1->_instance_words < e2->_instance_words) { 43 return 1; 44 } 45 return 0; 46 } 47 48 void KlassInfoEntry::print_on(outputStream* st) const { 49 ResourceMark rm; 50 const char* name;; 51 if (_klass->klass_part()->name() != NULL) { 52 name = _klass->klass_part()->external_name(); 53 } else { 54 if (_klass == Universe::klassKlassObj()) name = "<klassKlass>"; else 55 if (_klass == Universe::arrayKlassKlassObj()) name = "<arrayKlassKlass>"; else 56 if (_klass == Universe::objArrayKlassKlassObj()) name = "<objArrayKlassKlass>"; else 57 if (_klass == Universe::instanceKlassKlassObj()) name = "<instanceKlassKlass>"; else 58 if (_klass == Universe::typeArrayKlassKlassObj()) name = "<typeArrayKlassKlass>"; else 59 if (_klass == Universe::boolArrayKlassObj()) name = "<boolArrayKlass>"; else 60 if (_klass == Universe::charArrayKlassObj()) name = "<charArrayKlass>"; else 61 if (_klass == Universe::singleArrayKlassObj()) name = "<singleArrayKlass>"; else 62 if (_klass == Universe::doubleArrayKlassObj()) name = "<doubleArrayKlass>"; else 63 if (_klass == Universe::byteArrayKlassObj()) name = "<byteArrayKlass>"; else 64 if (_klass == Universe::shortArrayKlassObj()) name = "<shortArrayKlass>"; else 65 if (_klass == Universe::intArrayKlassObj()) name = "<intArrayKlass>"; else 66 if (_klass == Universe::longArrayKlassObj()) name = "<longArrayKlass>"; else 67 if (_klass == Universe::methodKlassObj()) name = "<methodKlass>"; else 68 if (_klass == Universe::constMethodKlassObj()) name = "<constMethodKlass>"; else 69 if (_klass == Universe::methodDataKlassObj()) name = "<methodDataKlass>"; else 70 if (_klass == Universe::constantPoolKlassObj()) name = "<constantPoolKlass>"; else 71 if (_klass == Universe::constantPoolCacheKlassObj()) name = "<constantPoolCacheKlass>"; else 72 if (_klass == Universe::compiledICHolderKlassObj()) name = "<compiledICHolderKlass>"; else 73 name = "<no name>"; 74 } 75 // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit 76 st->print_cr(INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13) " %s", 77 (jlong) _instance_count, 78 (julong) _instance_words * HeapWordSize, 79 name); 80 } 81 82 KlassInfoEntry* KlassInfoBucket::lookup(const klassOop k) { 83 KlassInfoEntry* elt = _list; 84 while (elt != NULL) { 85 if (elt->is_equal(k)) { 86 return elt; 87 } 88 elt = elt->next(); 89 } 90 elt = new (std::nothrow) KlassInfoEntry(k, list()); 91 // We may be out of space to allocate the new entry. 92 if (elt != NULL) { 93 set_list(elt); 94 } 95 return elt; 96 } 97 98 void KlassInfoBucket::iterate(KlassInfoClosure* cic) { 99 KlassInfoEntry* elt = _list; 100 while (elt != NULL) { 101 cic->do_cinfo(elt); 102 elt = elt->next(); 103 } 104 } 105 106 void KlassInfoBucket::empty() { 107 KlassInfoEntry* elt = _list; 108 _list = NULL; 109 while (elt != NULL) { 110 KlassInfoEntry* next = elt->next(); 111 delete elt; 112 elt = next; 113 } 114 } 115 116 KlassInfoTable::KlassInfoTable(HeapWord* ref) { 117 _size = 0; 118 _ref = ref; 119 _buckets = (KlassInfoBucket *) os::malloc(sizeof(KlassInfoBucket) * _num_buckets, mtInternal); 120 if (_buckets != NULL) { 121 _size = _num_buckets; 122 for (int index = 0; index < _size; index++) { 123 _buckets[index].initialize(); 124 } 125 } 126 } 127 128 KlassInfoTable::~KlassInfoTable() { 129 if (_buckets != NULL) { 130 for (int index = 0; index < _size; index++) { 131 _buckets[index].empty(); 132 } 133 FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets, mtInternal); 134 _size = 0; 135 } 136 } 137 138 uint KlassInfoTable::hash(klassOop p) { 139 assert(Universe::heap()->is_in_permanent((HeapWord*)p), "all klasses in permgen"); 140 return (uint)(((uintptr_t)p - (uintptr_t)_ref) >> 2); 141 } 142 143 KlassInfoEntry* KlassInfoTable::lookup(const klassOop k) { 144 uint idx = hash(k) % _size; 145 assert(_buckets != NULL, "Allocation failure should have been caught"); 146 KlassInfoEntry* e = _buckets[idx].lookup(k); 147 // Lookup may fail if this is a new klass for which we 148 // could not allocate space for an new entry. 149 assert(e == NULL || k == e->klass(), "must be equal"); 150 return e; 151 } 152 153 // Return false if the entry could not be recorded on account 154 // of running out of space required to create a new entry. 155 bool KlassInfoTable::record_instance(const oop obj) { 156 klassOop k = obj->klass(); 157 KlassInfoEntry* elt = lookup(k); 158 // elt may be NULL if it's a new klass for which we 159 // could not allocate space for a new entry in the hashtable. 160 if (elt != NULL) { 161 elt->set_count(elt->count() + 1); 162 elt->set_words(elt->words() + obj->size()); 163 return true; 164 } else { 165 return false; 166 } 167 } 168 169 void KlassInfoTable::iterate(KlassInfoClosure* cic) { 170 assert(_size == 0 || _buckets != NULL, "Allocation failure should have been caught"); 171 for (int index = 0; index < _size; index++) { 172 _buckets[index].iterate(cic); 173 } 174 } 175 176 int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) { 177 return (*e1)->compare(*e1,*e2); 178 } 179 180 KlassInfoHisto::KlassInfoHisto(const char* title) : 181 _title(title) { 182 _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(_histo_initial_size, true); 183 } 184 185 KlassInfoHisto::~KlassInfoHisto() { 186 delete _elements; 187 } 188 189 void KlassInfoHisto::add(KlassInfoEntry* cie) { 190 elements()->append(cie); 191 } 192 193 void KlassInfoHisto::sort() { 194 elements()->sort(KlassInfoHisto::sort_helper); 195 } 196 197 void KlassInfoHisto::print_elements(outputStream* st) const { 198 // simplify the formatting (ILP32 vs LP64) - store the sum in 64-bit 199 jlong total = 0; 200 julong totalw = 0; 201 for(int i=0; i < elements()->length(); i++) { 202 st->print("%4d: ", i+1); 203 elements()->at(i)->print_on(st); 204 total += elements()->at(i)->count(); 205 totalw += elements()->at(i)->words(); 206 } 207 st->print_cr("Total " INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13), 208 total, totalw * HeapWordSize); 209 } 210 211 void KlassInfoHisto::print_on(outputStream* st) const { 212 st->print_cr("%s",title()); 213 print_elements(st); 214 } 215 216 class HistoClosure : public KlassInfoClosure { 217 private: 218 KlassInfoHisto* _cih; 219 public: 220 HistoClosure(KlassInfoHisto* cih) : _cih(cih) {} 221 222 void do_cinfo(KlassInfoEntry* cie) { 223 _cih->add(cie); 224 } 225 }; 226 227 class RecordInstanceClosure : public ObjectClosure { 228 private: 229 KlassInfoTable* _cit; 230 size_t _missed_count; 231 BoolObjectClosure* _filter; 232 public: 233 RecordInstanceClosure(KlassInfoTable* cit, BoolObjectClosure* filter) : 234 _cit(cit), _missed_count(0), _filter(filter) {} 235 236 void do_object(oop obj) { 237 if (should_visit(obj)) { 238 if (!_cit->record_instance(obj)) { 239 _missed_count++; 240 } 241 } 242 } 243 244 size_t missed_count() { return _missed_count; } 245 private: 246 bool should_visit(oop obj) { 247 return _filter == NULL || _filter->do_object_b(obj); 248 } 249 }; 250 251 HeapWord* HeapInspection::start_of_perm_gen() { 252 if (is_shared_heap()) { 253 SharedHeap* sh = SharedHeap::heap(); 254 return sh->perm_gen()->used_region().start(); 255 } 256 #ifndef SERIALGC 257 ParallelScavengeHeap* psh = (ParallelScavengeHeap*)Universe::heap(); 258 return psh->perm_gen()->object_space()->used_region().start(); 259 #else 260 ShouldNotReachHere(); 261 return NULL; 262 #endif // SERIALGC 263 } 264 265 bool HeapInspection::is_shared_heap() { 266 CollectedHeap* heap = Universe::heap(); 267 return heap->kind() == CollectedHeap::G1CollectedHeap || 268 heap->kind() == CollectedHeap::GenCollectedHeap; 269 } 270 271 void HeapInspection::prologue() { 272 if (is_shared_heap()) { 273 SharedHeap* sh = SharedHeap::heap(); 274 sh->gc_prologue(false /* !full */); // get any necessary locks, etc. 275 } 276 } 277 278 void HeapInspection::epilogue() { 279 if (is_shared_heap()) { 280 SharedHeap* sh = SharedHeap::heap(); 281 sh->gc_epilogue(false /* !full */); // release all acquired locks, etc. 282 } 283 } 284 285 size_t HeapInspection::instance_inspection(KlassInfoTable* cit, 286 KlassInfoClosure* cl, 287 bool need_prologue, 288 BoolObjectClosure* filter) { 289 ResourceMark rm; 290 291 if (need_prologue) { 292 prologue(); 293 } 294 295 RecordInstanceClosure ric(cit, filter); 296 Universe::heap()->object_iterate(&ric); 297 cit->iterate(cl); 298 299 // need to run epilogue if we run prologue 300 if (need_prologue) { 301 epilogue(); 302 } 303 304 return ric.missed_count(); 305 } 306 307 void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) { 308 ResourceMark rm; 309 310 KlassInfoTable cit(start_of_perm_gen()); 311 if (!cit.allocation_failed()) { 312 KlassInfoHisto histo("\n" 313 " num #instances #bytes class name\n" 314 "----------------------------------------------"); 315 HistoClosure hc(&histo); 316 317 size_t missed_count = instance_inspection(&cit, &hc, need_prologue); 318 if (missed_count != 0) { 319 st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT 320 " total instances in data below", 321 missed_count); 322 } 323 histo.sort(); 324 histo.print_on(st); 325 } else { 326 st->print_cr("WARNING: Ran out of C-heap; histogram not generated"); 327 } 328 st->flush(); 329 } 330 331 class FindInstanceClosure : public ObjectClosure { 332 private: 333 klassOop _klass; 334 GrowableArray<oop>* _result; 335 336 public: 337 FindInstanceClosure(klassOop k, GrowableArray<oop>* result) : _klass(k), _result(result) {}; 338 339 void do_object(oop obj) { 340 if (obj->is_a(_klass)) { 341 _result->append(obj); 342 } 343 } 344 }; 345 346 void HeapInspection::find_instances_at_safepoint(klassOop k, GrowableArray<oop>* result) { 347 assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped"); 348 assert(Heap_lock->is_locked(), "should have the Heap_lock"); 349 350 // Ensure that the heap is parsable 351 Universe::heap()->ensure_parsability(false); // no need to retire TALBs 352 353 // Iterate over objects in the heap 354 FindInstanceClosure fic(k, result); 355 // If this operation encounters a bad object when using CMS, 356 // consider using safe_object_iterate() which avoids perm gen 357 // objects that may contain bad references. 358 Universe::heap()->object_iterate(&fic); 359 }