src/share/vm/memory/heapInspection.cpp

Print this page
rev 4773 : 8005849: JEP 167: Event-Based JVM Tracing
Reviewed-by: acorn, coleenp, sla
Contributed-by: Karen Kinnear <karen.kinnear@oracle.com>, Bengt Rutisson <bengt.rutisson@oracle.com>, Calvin Cheung <calvin.cheung@oracle.com>, Erik Gahlin <erik.gahlin@oracle.com>, Erik Helin <erik.helin@oracle.com>, Jesper Wilhelmsson <jesper.wilhelmsson@oracle.com>, Keith McGuigan <keith.mcguigan@oracle.com>, Mattias Tobiasson <mattias.tobiasson@oracle.com>, Markus Gronlund <markus.gronlund@oracle.com>, Mikael Auno <mikael.auno@oracle.com>, Nils Eliasson <nils.eliasson@oracle.com>, Nils Loodin <nils.loodin@oracle.com>, Rickard Backman <rickard.backman@oracle.com>, Staffan Larsen <staffan.larsen@oracle.com>, Stefan Karlsson <stefan.karlsson@oracle.com>, Yekaterina Kantserova <yekaterina.kantserova@oracle.com>


  78 }
  79 
  80 void KlassInfoEntry::print_on(outputStream* st) const {
  81   ResourceMark rm;
  82 
  83   // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit
  84   st->print_cr(INT64_FORMAT_W(13) "  " UINT64_FORMAT_W(13) "  %s",
  85                (jlong)  _instance_count,
  86                (julong) _instance_words * HeapWordSize,
  87                name());
  88 }
  89 
  90 KlassInfoEntry* KlassInfoBucket::lookup(Klass* const k) {
  91   KlassInfoEntry* elt = _list;
  92   while (elt != NULL) {
  93     if (elt->is_equal(k)) {
  94       return elt;
  95     }
  96     elt = elt->next();
  97   }
  98   elt = new KlassInfoEntry(k, list());
  99   // We may be out of space to allocate the new entry.
 100   if (elt != NULL) {
 101     set_list(elt);
 102   }
 103   return elt;
 104 }
 105 
 106 void KlassInfoBucket::iterate(KlassInfoClosure* cic) {
 107   KlassInfoEntry* elt = _list;
 108   while (elt != NULL) {
 109     cic->do_cinfo(elt);
 110     elt = elt->next();
 111   }
 112 }
 113 
 114 void KlassInfoBucket::empty() {
 115   KlassInfoEntry* elt = _list;
 116   _list = NULL;
 117   while (elt != NULL) {
 118     KlassInfoEntry* next = elt->next();
 119     delete elt;
 120     elt = next;
 121   }
 122 }
 123 
 124 void KlassInfoTable::AllClassesFinder::do_klass(Klass* k) {
 125   // This has the SIDE EFFECT of creating a KlassInfoEntry
 126   // for <k>, if one doesn't exist yet.
 127   _table->lookup(k);
 128 }
 129 
 130 KlassInfoTable::KlassInfoTable(int size, HeapWord* ref,
 131                                bool need_class_stats) {
 132   _size = 0;
 133   _ref = ref;
 134   _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size, mtInternal);


 135   if (_buckets != NULL) {
 136     _size = size;
 137     for (int index = 0; index < _size; index++) {
 138       _buckets[index].initialize();
 139     }
 140     if (need_class_stats) {
 141       AllClassesFinder finder(this);
 142       ClassLoaderDataGraph::classes_do(&finder);
 143     }
 144   }
 145 }
 146 
 147 KlassInfoTable::~KlassInfoTable() {
 148   if (_buckets != NULL) {
 149     for (int index = 0; index < _size; index++) {
 150       _buckets[index].empty();
 151     }
 152     FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets, mtInternal);
 153     _size = 0;
 154   }
 155 }
 156 


 162 KlassInfoEntry* KlassInfoTable::lookup(Klass* k) {
 163   uint         idx = hash(k) % _size;
 164   assert(_buckets != NULL, "Allocation failure should have been caught");
 165   KlassInfoEntry*  e   = _buckets[idx].lookup(k);
 166   // Lookup may fail if this is a new klass for which we
 167   // could not allocate space for an new entry.
 168   assert(e == NULL || k == e->klass(), "must be equal");
 169   return e;
 170 }
 171 
 172 // Return false if the entry could not be recorded on account
 173 // of running out of space required to create a new entry.
 174 bool KlassInfoTable::record_instance(const oop obj) {
 175   Klass*        k = obj->klass();
 176   KlassInfoEntry* elt = lookup(k);
 177   // elt may be NULL if it's a new klass for which we
 178   // could not allocate space for a new entry in the hashtable.
 179   if (elt != NULL) {
 180     elt->set_count(elt->count() + 1);
 181     elt->set_words(elt->words() + obj->size());

 182     return true;
 183   } else {
 184     return false;
 185   }
 186 }
 187 
 188 void KlassInfoTable::iterate(KlassInfoClosure* cic) {
 189   assert(_size == 0 || _buckets != NULL, "Allocation failure should have been caught");
 190   for (int index = 0; index < _size; index++) {
 191     _buckets[index].iterate(cic);
 192   }
 193 }
 194 




 195 int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) {
 196   return (*e1)->compare(*e1,*e2);
 197 }
 198 
 199 KlassInfoHisto::KlassInfoHisto(KlassInfoTable* cit, const char* title, int estimatedCount) :
 200   _cit(cit),
 201   _title(title) {
 202   _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(estimatedCount,true);
 203 }
 204 
 205 KlassInfoHisto::~KlassInfoHisto() {
 206   delete _elements;
 207 }
 208 
 209 void KlassInfoHisto::add(KlassInfoEntry* cie) {
 210   elements()->append(cie);
 211 }
 212 
 213 void KlassInfoHisto::sort() {
 214   elements()->sort(KlassInfoHisto::sort_helper);
 215 }
 216 
 217 void KlassInfoHisto::print_elements(outputStream* st) const {
 218   // simplify the formatting (ILP32 vs LP64) - store the sum in 64-bit
 219   jlong total = 0;
 220   julong totalw = 0;
 221   for(int i=0; i < elements()->length(); i++) {
 222     st->print("%4d: ", i+1);


 427     st->print_cr("%s",title());
 428     print_elements(st);
 429   }
 430 }
 431 
 432 class HistoClosure : public KlassInfoClosure {
 433  private:
 434   KlassInfoHisto* _cih;
 435  public:
 436   HistoClosure(KlassInfoHisto* cih) : _cih(cih) {}
 437 
 438   void do_cinfo(KlassInfoEntry* cie) {
 439     _cih->add(cie);
 440   }
 441 };
 442 
 443 class RecordInstanceClosure : public ObjectClosure {
 444  private:
 445   KlassInfoTable* _cit;
 446   size_t _missed_count;

 447  public:
 448   RecordInstanceClosure(KlassInfoTable* cit) :
 449     _cit(cit), _missed_count(0) {}
 450 
 451   void do_object(oop obj) {

 452     if (!_cit->record_instance(obj)) {
 453       _missed_count++;
 454     }
 455   }

 456 
 457   size_t missed_count() { return _missed_count; }





 458 };
 459 
 460 void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) {








 461   ResourceMark rm;
 462   // Get some random number for ref (the hash key)
 463   HeapWord* ref = (HeapWord*) Universe::boolArrayKlassObj();
 464   CollectedHeap* heap = Universe::heap();
 465   bool is_shared_heap = false;
 466 
 467   if (_print_help) {
 468     for (int c=0; c<KlassSizeStats::_num_columns; c++) {
 469       st->print("%s:\n\t", name_table[c]);
 470       const int max_col = 60;
 471       int col = 0;
 472       for (const char *p = help_table[c]; *p; p++,col++) {
 473         if (col >= max_col && *p == ' ') {
 474           st->print("\n\t");
 475           col = 0;
 476         } else {
 477           st->print("%c", *p);
 478         }
 479       }
 480       st->print_cr(".\n");
 481     }
 482     return;
 483   }
 484 
 485   // Collect klass instance info
 486   KlassInfoTable cit(KlassInfoTable::cit_size, ref, _print_class_stats);
 487   if (!cit.allocation_failed()) {
 488     // Iterate over objects in the heap
 489     RecordInstanceClosure ric(&cit);
 490     Universe::heap()->object_iterate(&ric);
 491 
 492     // Report if certain classes are not counted because of
 493     // running out of C-heap for the histogram.
 494     size_t missed_count = ric.missed_count();
 495     if (missed_count != 0) {
 496       st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
 497                    " total instances in data below",
 498                    missed_count);
 499     }

 500     // Sort and print klass instance info
 501     const char *title = "\n"
 502               " num     #instances         #bytes  class name\n"
 503               "----------------------------------------------";
 504     KlassInfoHisto histo(&cit, title, KlassInfoHisto::histo_initial_size);
 505     HistoClosure hc(&histo);

 506     cit.iterate(&hc);

 507     histo.sort();
 508     histo.print_histo_on(st, _print_class_stats, _csv_format, _columns);
 509   } else {
 510     st->print_cr("WARNING: Ran out of C-heap; histogram not generated");
 511   }
 512   st->flush();
 513 
 514   if (need_prologue && is_shared_heap) {
 515     SharedHeap* sh = (SharedHeap*)heap;
 516     sh->gc_epilogue(false /* !full */); // release all acquired locks, etc.
 517   }
 518 }
 519 
 520 class FindInstanceClosure : public ObjectClosure {
 521  private:
 522   Klass* _klass;
 523   GrowableArray<oop>* _result;
 524 
 525  public:
 526   FindInstanceClosure(Klass* k, GrowableArray<oop>* result) : _klass(k), _result(result) {};
 527 
 528   void do_object(oop obj) {
 529     if (obj->is_a(_klass)) {
 530       _result->append(obj);
 531     }
 532   }
 533 };
 534 
 535 void HeapInspection::find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) {
 536   assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped");
 537   assert(Heap_lock->is_locked(), "should have the Heap_lock");


  78 }
  79 
  80 void KlassInfoEntry::print_on(outputStream* st) const {
  81   ResourceMark rm;
  82 
  83   // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit
  84   st->print_cr(INT64_FORMAT_W(13) "  " UINT64_FORMAT_W(13) "  %s",
  85                (jlong)  _instance_count,
  86                (julong) _instance_words * HeapWordSize,
  87                name());
  88 }
  89 
  90 KlassInfoEntry* KlassInfoBucket::lookup(Klass* const k) {
  91   KlassInfoEntry* elt = _list;
  92   while (elt != NULL) {
  93     if (elt->is_equal(k)) {
  94       return elt;
  95     }
  96     elt = elt->next();
  97   }
  98   elt = new (std::nothrow) KlassInfoEntry(k, list());
  99   // We may be out of space to allocate the new entry.
 100   if (elt != NULL) {
 101     set_list(elt);
 102   }
 103   return elt;
 104 }
 105 
 106 void KlassInfoBucket::iterate(KlassInfoClosure* cic) {
 107   KlassInfoEntry* elt = _list;
 108   while (elt != NULL) {
 109     cic->do_cinfo(elt);
 110     elt = elt->next();
 111   }
 112 }
 113 
 114 void KlassInfoBucket::empty() {
 115   KlassInfoEntry* elt = _list;
 116   _list = NULL;
 117   while (elt != NULL) {
 118     KlassInfoEntry* next = elt->next();
 119     delete elt;
 120     elt = next;
 121   }
 122 }
 123 
 124 void KlassInfoTable::AllClassesFinder::do_klass(Klass* k) {
 125   // This has the SIDE EFFECT of creating a KlassInfoEntry
 126   // for <k>, if one doesn't exist yet.
 127   _table->lookup(k);
 128 }
 129 
 130 KlassInfoTable::KlassInfoTable(bool need_class_stats) {
 131   _size_of_instances_in_words = 0;
 132   _size = 0;
 133   _ref = (HeapWord*) Universe::boolArrayKlassObj();
 134   _buckets =
 135     (KlassInfoBucket*)  AllocateHeap(sizeof(KlassInfoBucket) * _num_buckets,
 136                                             mtInternal, 0, AllocFailStrategy::RETURN_NULL);
 137   if (_buckets != NULL) {
 138     _size = _num_buckets;
 139     for (int index = 0; index < _size; index++) {
 140       _buckets[index].initialize();
 141     }
 142     if (need_class_stats) {
 143       AllClassesFinder finder(this);
 144       ClassLoaderDataGraph::classes_do(&finder);
 145     }
 146   }
 147 }
 148 
 149 KlassInfoTable::~KlassInfoTable() {
 150   if (_buckets != NULL) {
 151     for (int index = 0; index < _size; index++) {
 152       _buckets[index].empty();
 153     }
 154     FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets, mtInternal);
 155     _size = 0;
 156   }
 157 }
 158 


 164 KlassInfoEntry* KlassInfoTable::lookup(Klass* k) {
 165   uint         idx = hash(k) % _size;
 166   assert(_buckets != NULL, "Allocation failure should have been caught");
 167   KlassInfoEntry*  e   = _buckets[idx].lookup(k);
 168   // Lookup may fail if this is a new klass for which we
 169   // could not allocate space for an new entry.
 170   assert(e == NULL || k == e->klass(), "must be equal");
 171   return e;
 172 }
 173 
 174 // Return false if the entry could not be recorded on account
 175 // of running out of space required to create a new entry.
 176 bool KlassInfoTable::record_instance(const oop obj) {
 177   Klass*        k = obj->klass();
 178   KlassInfoEntry* elt = lookup(k);
 179   // elt may be NULL if it's a new klass for which we
 180   // could not allocate space for a new entry in the hashtable.
 181   if (elt != NULL) {
 182     elt->set_count(elt->count() + 1);
 183     elt->set_words(elt->words() + obj->size());
 184     _size_of_instances_in_words += obj->size();
 185     return true;
 186   } else {
 187     return false;
 188   }
 189 }
 190 
 191 void KlassInfoTable::iterate(KlassInfoClosure* cic) {
 192   assert(_size == 0 || _buckets != NULL, "Allocation failure should have been caught");
 193   for (int index = 0; index < _size; index++) {
 194     _buckets[index].iterate(cic);
 195   }
 196 }
 197 
 198 size_t KlassInfoTable::size_of_instances_in_words() const {
 199   return _size_of_instances_in_words;
 200 }
 201 
 202 int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) {
 203   return (*e1)->compare(*e1,*e2);
 204 }
 205 
 206 KlassInfoHisto::KlassInfoHisto(KlassInfoTable* cit, const char* title) :
 207   _cit(cit),
 208   _title(title) {
 209   _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(_histo_initial_size, true);
 210 }
 211 
 212 KlassInfoHisto::~KlassInfoHisto() {
 213   delete _elements;
 214 }
 215 
 216 void KlassInfoHisto::add(KlassInfoEntry* cie) {
 217   elements()->append(cie);
 218 }
 219 
 220 void KlassInfoHisto::sort() {
 221   elements()->sort(KlassInfoHisto::sort_helper);
 222 }
 223 
 224 void KlassInfoHisto::print_elements(outputStream* st) const {
 225   // simplify the formatting (ILP32 vs LP64) - store the sum in 64-bit
 226   jlong total = 0;
 227   julong totalw = 0;
 228   for(int i=0; i < elements()->length(); i++) {
 229     st->print("%4d: ", i+1);


 434     st->print_cr("%s",title());
 435     print_elements(st);
 436   }
 437 }
 438 
 439 class HistoClosure : public KlassInfoClosure {
 440  private:
 441   KlassInfoHisto* _cih;
 442  public:
 443   HistoClosure(KlassInfoHisto* cih) : _cih(cih) {}
 444 
 445   void do_cinfo(KlassInfoEntry* cie) {
 446     _cih->add(cie);
 447   }
 448 };
 449 
 450 class RecordInstanceClosure : public ObjectClosure {
 451  private:
 452   KlassInfoTable* _cit;
 453   size_t _missed_count;
 454   BoolObjectClosure* _filter;
 455  public:
 456   RecordInstanceClosure(KlassInfoTable* cit, BoolObjectClosure* filter) :
 457     _cit(cit), _missed_count(0), _filter(filter) {}
 458 
 459   void do_object(oop obj) {
 460     if (should_visit(obj)) {
 461       if (!_cit->record_instance(obj)) {
 462         _missed_count++;
 463       }
 464     }
 465   }
 466 
 467   size_t missed_count() { return _missed_count; }
 468 
 469  private:
 470   bool should_visit(oop obj) {
 471     return _filter == NULL || _filter->do_object_b(obj);
 472   }
 473 };
 474 
 475 size_t HeapInspection::populate_table(KlassInfoTable* cit, BoolObjectClosure *filter) {
 476   ResourceMark rm;
 477 
 478   RecordInstanceClosure ric(cit, filter);
 479   Universe::heap()->object_iterate(&ric);
 480   return ric.missed_count();
 481 }
 482 
 483 void HeapInspection::heap_inspection(outputStream* st) {
 484   ResourceMark rm;




 485 
 486   if (_print_help) {
 487     for (int c=0; c<KlassSizeStats::_num_columns; c++) {
 488       st->print("%s:\n\t", name_table[c]);
 489       const int max_col = 60;
 490       int col = 0;
 491       for (const char *p = help_table[c]; *p; p++,col++) {
 492         if (col >= max_col && *p == ' ') {
 493           st->print("\n\t");
 494           col = 0;
 495         } else {
 496           st->print("%c", *p);
 497         }
 498       }
 499       st->print_cr(".\n");
 500     }
 501     return;
 502   }
 503 
 504   KlassInfoTable cit(_print_class_stats);

 505   if (!cit.allocation_failed()) {
 506     size_t missed_count = populate_table(&cit);






 507     if (missed_count != 0) {
 508       st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
 509                    " total instances in data below",
 510                    missed_count);
 511     }
 512 
 513     // Sort and print klass instance info
 514     const char *title = "\n"
 515               " num     #instances         #bytes  class name\n"
 516               "----------------------------------------------";
 517     KlassInfoHisto histo(&cit, title);
 518     HistoClosure hc(&histo);
 519 
 520     cit.iterate(&hc);
 521 
 522     histo.sort();
 523     histo.print_histo_on(st, _print_class_stats, _csv_format, _columns);
 524   } else {
 525     st->print_cr("WARNING: Ran out of C-heap; histogram not generated");
 526   }
 527   st->flush();





 528 }
 529 
 530 class FindInstanceClosure : public ObjectClosure {
 531  private:
 532   Klass* _klass;
 533   GrowableArray<oop>* _result;
 534 
 535  public:
 536   FindInstanceClosure(Klass* k, GrowableArray<oop>* result) : _klass(k), _result(result) {};
 537 
 538   void do_object(oop obj) {
 539     if (obj->is_a(_klass)) {
 540       _result->append(obj);
 541     }
 542   }
 543 };
 544 
 545 void HeapInspection::find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) {
 546   assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped");
 547   assert(Heap_lock->is_locked(), "should have the Heap_lock");