hotspot/src/share/vm/memory/heapInspection.cpp
changeset 184 a2da5efb871c
parent 1 489c9b5090e2
child 670 ddf3e9583f2f
child 1374 4c24294029a9
equal deleted inserted replaced
183:ba55c7f3fd45 184:a2da5efb871c
    63     if (_klass == Universe::constantPoolCacheKlassObj()) name = "<constantPoolCacheKlass>"; else
    63     if (_klass == Universe::constantPoolCacheKlassObj()) name = "<constantPoolCacheKlass>"; else
    64     if (_klass == Universe::compiledICHolderKlassObj())  name = "<compiledICHolderKlass>";  else
    64     if (_klass == Universe::compiledICHolderKlassObj())  name = "<compiledICHolderKlass>";  else
    65       name = "<no name>";
    65       name = "<no name>";
    66   }
    66   }
    67   // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit
    67   // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit
    68   st->print_cr("%13" FORMAT64_MODIFIER "d  %13" FORMAT64_MODIFIER "u  %s",
    68   st->print_cr(INT64_FORMAT_W(13) "  " UINT64_FORMAT_W(13) "  %s",
    69                (jlong)  _instance_count,
    69                (jlong)  _instance_count,
    70                (julong) _instance_words * HeapWordSize,
    70                (julong) _instance_words * HeapWordSize,
    71                name);
    71                name);
    72 }
    72 }
    73 
    73 
    78       return elt;
    78       return elt;
    79     }
    79     }
    80     elt = elt->next();
    80     elt = elt->next();
    81   }
    81   }
    82   elt = new KlassInfoEntry(k, list());
    82   elt = new KlassInfoEntry(k, list());
    83   set_list(elt);
    83   // We may be out of space to allocate the new entry.
       
    84   if (elt != NULL) {
       
    85     set_list(elt);
       
    86   }
    84   return elt;
    87   return elt;
    85 }
    88 }
    86 
    89 
    87 void KlassInfoBucket::iterate(KlassInfoClosure* cic) {
    90 void KlassInfoBucket::iterate(KlassInfoClosure* cic) {
    88   KlassInfoEntry* elt = _list;
    91   KlassInfoEntry* elt = _list;
   101     elt = next;
   104     elt = next;
   102   }
   105   }
   103 }
   106 }
   104 
   107 
   105 KlassInfoTable::KlassInfoTable(int size, HeapWord* ref) {
   108 KlassInfoTable::KlassInfoTable(int size, HeapWord* ref) {
   106   _size = size;
   109   _size = 0;
   107   _ref = ref;
   110   _ref = ref;
   108   _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, _size);
   111   _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size);
   109 
   112   if (_buckets != NULL) {
   110   for (int index = 0; index < _size; index++) {
   113     _size = size;
   111     _buckets[index].initialize();
   114     for (int index = 0; index < _size; index++) {
       
   115       _buckets[index].initialize();
       
   116     }
   112   }
   117   }
   113 }
   118 }
   114 
   119 
   115 KlassInfoTable::~KlassInfoTable() {
   120 KlassInfoTable::~KlassInfoTable() {
   116   for (int index = 0; index < _size; index++) {
   121   if (_buckets != NULL) {
   117     _buckets[index].empty();
   122     for (int index = 0; index < _size; index++) {
   118   }
   123       _buckets[index].empty();
   119   FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets);
   124     }
   120   _size = 0;
   125     FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets);
       
   126     _size = 0;
       
   127   }
   121 }
   128 }
   122 
   129 
   123 uint KlassInfoTable::hash(klassOop p) {
   130 uint KlassInfoTable::hash(klassOop p) {
   124   assert(Universe::heap()->is_in_permanent((HeapWord*)p), "all klasses in permgen");
   131   assert(Universe::heap()->is_in_permanent((HeapWord*)p), "all klasses in permgen");
   125   return (uint)(((uintptr_t)p - (uintptr_t)_ref) >> 2);
   132   return (uint)(((uintptr_t)p - (uintptr_t)_ref) >> 2);
   126 }
   133 }
   127 
   134 
   128 KlassInfoEntry* KlassInfoTable::lookup(const klassOop k) {
   135 KlassInfoEntry* KlassInfoTable::lookup(const klassOop k) {
   129   uint         idx = hash(k) % _size;
   136   uint         idx = hash(k) % _size;
       
   137   assert(_buckets != NULL, "Allocation failure should have been caught");
   130   KlassInfoEntry*  e   = _buckets[idx].lookup(k);
   138   KlassInfoEntry*  e   = _buckets[idx].lookup(k);
   131   assert(k == e->klass(), "must be equal");
   139   // Lookup may fail if this is a new klass for which we
       
   140   // could not allocate space for an new entry.
       
   141   assert(e == NULL || k == e->klass(), "must be equal");
   132   return e;
   142   return e;
   133 }
   143 }
   134 
   144 
   135 void KlassInfoTable::record_instance(const oop obj) {
   145 // Return false if the entry could not be recorded on account
       
   146 // of running out of space required to create a new entry.
       
   147 bool KlassInfoTable::record_instance(const oop obj) {
   136   klassOop      k = obj->klass();
   148   klassOop      k = obj->klass();
   137   KlassInfoEntry* elt = lookup(k);
   149   KlassInfoEntry* elt = lookup(k);
   138   elt->set_count(elt->count() + 1);
   150   // elt may be NULL if it's a new klass for which we
   139   elt->set_words(elt->words() + obj->size());
   151   // could not allocate space for a new entry in the hashtable.
       
   152   if (elt != NULL) {
       
   153     elt->set_count(elt->count() + 1);
       
   154     elt->set_words(elt->words() + obj->size());
       
   155     return true;
       
   156   } else {
       
   157     return false;
       
   158   }
   140 }
   159 }
   141 
   160 
   142 void KlassInfoTable::iterate(KlassInfoClosure* cic) {
   161 void KlassInfoTable::iterate(KlassInfoClosure* cic) {
       
   162   assert(_size == 0 || _buckets != NULL, "Allocation failure should have been caught");
   143   for (int index = 0; index < _size; index++) {
   163   for (int index = 0; index < _size; index++) {
   144     _buckets[index].iterate(cic);
   164     _buckets[index].iterate(cic);
   145   }
   165   }
   146 }
   166 }
   147 
   167 
   174     st->print("%4d: ", i+1);
   194     st->print("%4d: ", i+1);
   175     elements()->at(i)->print_on(st);
   195     elements()->at(i)->print_on(st);
   176     total += elements()->at(i)->count();
   196     total += elements()->at(i)->count();
   177     totalw += elements()->at(i)->words();
   197     totalw += elements()->at(i)->words();
   178   }
   198   }
   179   st->print_cr("Total %13" FORMAT64_MODIFIER "d  %13" FORMAT64_MODIFIER "u",
   199   st->print_cr("Total " INT64_FORMAT_W(13) "  " UINT64_FORMAT_W(13),
   180                total, totalw * HeapWordSize);
   200                total, totalw * HeapWordSize);
   181 }
   201 }
   182 
   202 
   183 void KlassInfoHisto::print_on(outputStream* st) const {
   203 void KlassInfoHisto::print_on(outputStream* st) const {
   184   st->print_cr("%s",title());
   204   st->print_cr("%s",title());
   197 };
   217 };
   198 
   218 
   199 class RecordInstanceClosure : public ObjectClosure {
   219 class RecordInstanceClosure : public ObjectClosure {
   200  private:
   220  private:
   201   KlassInfoTable* _cit;
   221   KlassInfoTable* _cit;
       
   222   size_t _missed_count;
   202  public:
   223  public:
   203   RecordInstanceClosure(KlassInfoTable* cit) : _cit(cit) {}
   224   RecordInstanceClosure(KlassInfoTable* cit) :
       
   225     _cit(cit), _missed_count(0) {}
   204 
   226 
   205   void do_object(oop obj) {
   227   void do_object(oop obj) {
   206     _cit->record_instance(obj);
   228     if (!_cit->record_instance(obj)) {
   207   }
   229       _missed_count++;
       
   230     }
       
   231   }
       
   232 
       
   233   size_t missed_count() { return _missed_count; }
   208 };
   234 };
   209 
   235 
   210 void HeapInspection::heap_inspection(outputStream* st) {
   236 void HeapInspection::heap_inspection(outputStream* st) {
   211   ResourceMark rm;
   237   ResourceMark rm;
   212   HeapWord* ref;
   238   HeapWord* ref;
   228 #endif // SERIALGC
   254 #endif // SERIALGC
   229     default:
   255     default:
   230       ShouldNotReachHere(); // Unexpected heap kind for this op
   256       ShouldNotReachHere(); // Unexpected heap kind for this op
   231   }
   257   }
   232   // Collect klass instance info
   258   // Collect klass instance info
   233 
       
   234   // Iterate over objects in the heap
       
   235   KlassInfoTable cit(KlassInfoTable::cit_size, ref);
   259   KlassInfoTable cit(KlassInfoTable::cit_size, ref);
   236   RecordInstanceClosure ric(&cit);
   260   if (!cit.allocation_failed()) {
   237   Universe::heap()->object_iterate(&ric);
   261     // Iterate over objects in the heap
   238 
   262     RecordInstanceClosure ric(&cit);
   239   // Sort and print klass instance info
   263     Universe::heap()->object_iterate(&ric);
   240   KlassInfoHisto histo("\n"
   264 
   241                    " num     #instances         #bytes  class name\n"
   265     // Report if certain classes are not counted because of
   242                    "----------------------------------------------",
   266     // running out of C-heap for the histogram.
   243                    KlassInfoHisto::histo_initial_size);
   267     size_t missed_count = ric.missed_count();
   244   HistoClosure hc(&histo);
   268     if (missed_count != 0) {
   245   cit.iterate(&hc);
   269       st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
   246   histo.sort();
   270                    " total instances in data below",
   247   histo.print_on(st);
   271                    missed_count);
       
   272     }
       
   273     // Sort and print klass instance info
       
   274     KlassInfoHisto histo("\n"
       
   275                      " num     #instances         #bytes  class name\n"
       
   276                      "----------------------------------------------",
       
   277                      KlassInfoHisto::histo_initial_size);
       
   278     HistoClosure hc(&histo);
       
   279     cit.iterate(&hc);
       
   280     histo.sort();
       
   281     histo.print_on(st);
       
   282   } else {
       
   283     st->print_cr("WARNING: Ran out of C-heap; histogram not generated");
       
   284   }
   248   st->flush();
   285   st->flush();
   249 
   286 
   250   if (Universe::heap()->kind() == CollectedHeap::GenCollectedHeap) {
   287   if (Universe::heap()->kind() == CollectedHeap::GenCollectedHeap) {
   251     GenCollectedHeap* gch = GenCollectedHeap::heap();
   288     GenCollectedHeap* gch = GenCollectedHeap::heap();
   252     gch->gc_epilogue(false /* !full */); // release all acquired locks
   289     gch->gc_epilogue(false /* !full */); // release all acquired locks