hotspot/src/share/vm/memory/heapInspection.cpp
changeset 15437 eabd4555d072
parent 13728 882756847a04
child 15484 7395ace8a11a
equal deleted inserted replaced
15431:570c5062ab8a 15437:eabd4555d072
     1 /*
     1 /*
     2  * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    21  * questions.
    21  * questions.
    22  *
    22  *
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
       
    26 #include "classfile/classLoaderData.hpp"
    26 #include "gc_interface/collectedHeap.hpp"
    27 #include "gc_interface/collectedHeap.hpp"
    27 #include "memory/genCollectedHeap.hpp"
    28 #include "memory/genCollectedHeap.hpp"
    28 #include "memory/heapInspection.hpp"
    29 #include "memory/heapInspection.hpp"
    29 #include "memory/resourceArea.hpp"
    30 #include "memory/resourceArea.hpp"
    30 #include "runtime/os.hpp"
    31 #include "runtime/os.hpp"
    39   if(e1->_instance_words > e2->_instance_words) {
    40   if(e1->_instance_words > e2->_instance_words) {
    40     return -1;
    41     return -1;
    41   } else if(e1->_instance_words < e2->_instance_words) {
    42   } else if(e1->_instance_words < e2->_instance_words) {
    42     return 1;
    43     return 1;
    43   }
    44   }
    44   return 0;
    45   // Sort alphabetically, note 'Z' < '[' < 'a', but it's better to group
    45 }
    46   // the array classes before all the instance classes.
    46 
       
    47 void KlassInfoEntry::print_on(outputStream* st) const {
       
    48   ResourceMark rm;
    47   ResourceMark rm;
    49   const char* name;;
    48   const char* name1 = e1->klass()->external_name();
       
    49   const char* name2 = e2->klass()->external_name();
       
    50   bool d1 = (name1[0] == '[');
       
    51   bool d2 = (name2[0] == '[');
       
    52   if (d1 && !d2) {
       
    53     return -1;
       
    54   } else if (d2 && !d1) {
       
    55     return 1;
       
    56   } else {
       
    57     return strcmp(name1, name2);
       
    58   }
       
    59 }
       
    60 
       
    61 const char* KlassInfoEntry::name() const {
       
    62   const char* name;
    50   if (_klass->name() != NULL) {
    63   if (_klass->name() != NULL) {
    51     name = _klass->external_name();
    64     name = _klass->external_name();
    52   } else {
    65   } else {
    53     if (_klass == Universe::boolArrayKlassObj())         name = "<boolArrayKlass>";         else
    66     if (_klass == Universe::boolArrayKlassObj())         name = "<boolArrayKlass>";         else
    54     if (_klass == Universe::charArrayKlassObj())         name = "<charArrayKlass>";         else
    67     if (_klass == Universe::charArrayKlassObj())         name = "<charArrayKlass>";         else
    58     if (_klass == Universe::shortArrayKlassObj())        name = "<shortArrayKlass>";        else
    71     if (_klass == Universe::shortArrayKlassObj())        name = "<shortArrayKlass>";        else
    59     if (_klass == Universe::intArrayKlassObj())          name = "<intArrayKlass>";          else
    72     if (_klass == Universe::intArrayKlassObj())          name = "<intArrayKlass>";          else
    60     if (_klass == Universe::longArrayKlassObj())         name = "<longArrayKlass>";         else
    73     if (_klass == Universe::longArrayKlassObj())         name = "<longArrayKlass>";         else
    61       name = "<no name>";
    74       name = "<no name>";
    62   }
    75   }
       
    76   return name;
       
    77 }
       
    78 
       
    79 void KlassInfoEntry::print_on(outputStream* st) const {
       
    80   ResourceMark rm;
       
    81 
    63   // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit
    82   // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit
    64   st->print_cr(INT64_FORMAT_W(13) "  " UINT64_FORMAT_W(13) "  %s",
    83   st->print_cr(INT64_FORMAT_W(13) "  " UINT64_FORMAT_W(13) "  %s",
    65                (jlong)  _instance_count,
    84                (jlong)  _instance_count,
    66                (julong) _instance_words * HeapWordSize,
    85                (julong) _instance_words * HeapWordSize,
    67                name);
    86                name());
    68 }
    87 }
    69 
    88 
    70 KlassInfoEntry* KlassInfoBucket::lookup(Klass* const k) {
    89 KlassInfoEntry* KlassInfoBucket::lookup(Klass* const k) {
    71   KlassInfoEntry* elt = _list;
    90   KlassInfoEntry* elt = _list;
    72   while (elt != NULL) {
    91   while (elt != NULL) {
    99     delete elt;
   118     delete elt;
   100     elt = next;
   119     elt = next;
   101   }
   120   }
   102 }
   121 }
   103 
   122 
   104 KlassInfoTable::KlassInfoTable(int size, HeapWord* ref) {
   123 void KlassInfoTable::AllClassesFinder::do_klass(Klass* k) {
       
   124   // This has the SIDE EFFECT of creating a KlassInfoEntry
       
   125   // for <k>, if one doesn't exist yet.
       
   126   _table->lookup(k);
       
   127 }
       
   128 
       
   129 KlassInfoTable::KlassInfoTable(int size, HeapWord* ref,
       
   130                                bool need_class_stats) {
   105   _size = 0;
   131   _size = 0;
   106   _ref = ref;
   132   _ref = ref;
   107   _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size, mtInternal);
   133   _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size, mtInternal);
   108   if (_buckets != NULL) {
   134   if (_buckets != NULL) {
   109     _size = size;
   135     _size = size;
   110     for (int index = 0; index < _size; index++) {
   136     for (int index = 0; index < _size; index++) {
   111       _buckets[index].initialize();
   137       _buckets[index].initialize();
       
   138     }
       
   139     if (need_class_stats) {
       
   140       AllClassesFinder finder(this);
       
   141       ClassLoaderDataGraph::classes_do(&finder);
   112     }
   142     }
   113   }
   143   }
   114 }
   144 }
   115 
   145 
   116 KlassInfoTable::~KlassInfoTable() {
   146 KlassInfoTable::~KlassInfoTable() {
   163 
   193 
   164 int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) {
   194 int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) {
   165   return (*e1)->compare(*e1,*e2);
   195   return (*e1)->compare(*e1,*e2);
   166 }
   196 }
   167 
   197 
   168 KlassInfoHisto::KlassInfoHisto(const char* title, int estimatedCount) :
   198 KlassInfoHisto::KlassInfoHisto(KlassInfoTable* cit, const char* title, int estimatedCount) :
       
   199   _cit(cit),
   169   _title(title) {
   200   _title(title) {
   170   _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(estimatedCount,true);
   201   _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(estimatedCount,true);
   171 }
   202 }
   172 
   203 
   173 KlassInfoHisto::~KlassInfoHisto() {
   204 KlassInfoHisto::~KlassInfoHisto() {
   194   }
   225   }
   195   st->print_cr("Total " INT64_FORMAT_W(13) "  " UINT64_FORMAT_W(13),
   226   st->print_cr("Total " INT64_FORMAT_W(13) "  " UINT64_FORMAT_W(13),
   196                total, totalw * HeapWordSize);
   227                total, totalw * HeapWordSize);
   197 }
   228 }
   198 
   229 
   199 void KlassInfoHisto::print_on(outputStream* st) const {
   230 #define MAKE_COL_NAME(field, name, help)     #name,
   200   st->print_cr("%s",title());
   231 #define MAKE_COL_HELP(field, name, help)     help,
   201   print_elements(st);
   232 
       
   233 static const char *name_table[] = {
       
   234   HEAP_INSPECTION_COLUMNS_DO(MAKE_COL_NAME)
       
   235 };
       
   236 
       
   237 static const char *help_table[] = {
       
   238   HEAP_INSPECTION_COLUMNS_DO(MAKE_COL_HELP)
       
   239 };
       
   240 
       
   241 bool KlassInfoHisto::is_selected(const char *col_name) {
       
   242   if (_selected_columns == NULL) {
       
   243     return true;
       
   244   }
       
   245   if (strcmp(_selected_columns, col_name) == 0) {
       
   246     return true;
       
   247   }
       
   248 
       
   249   const char *start = strstr(_selected_columns, col_name);
       
   250   if (start == NULL) {
       
   251     return false;
       
   252   }
       
   253 
       
   254   // The following must be true, because _selected_columns != col_name
       
   255   if (start > _selected_columns && start[-1] != ',') {
       
   256     return false;
       
   257   }
       
   258   char x = start[strlen(col_name)];
       
   259   if (x != ',' && x != '\0') {
       
   260     return false;
       
   261   }
       
   262 
       
   263   return true;
       
   264 }
       
   265 
       
   266 void KlassInfoHisto::print_title(outputStream* st, bool csv_format,
       
   267                                  bool selected[], int width_table[],
       
   268                                  const char *name_table[]) {
       
   269   if (csv_format) {
       
   270     st->print("Index,Super");
       
   271     for (int c=0; c<KlassSizeStats::_num_columns; c++) {
       
   272        if (selected[c]) {st->print(",%s", name_table[c]);}
       
   273     }
       
   274     st->print(",ClassName");
       
   275   } else {
       
   276     st->print("Index Super");
       
   277     for (int c=0; c<KlassSizeStats::_num_columns; c++) {
       
   278       if (selected[c]) {st->print(str_fmt(width_table[c]), name_table[c]);}
       
   279     }
       
   280     st->print(" ClassName");
       
   281   }
       
   282 
       
   283   if (is_selected("ClassLoader")) {
       
   284     st->print(",ClassLoader");
       
   285   }
       
   286   st->cr();
       
   287 }
       
   288 
       
   289 void KlassInfoHisto::print_class_stats(outputStream* st,
       
   290                                       bool csv_format, const char *columns) {
       
   291   ResourceMark rm;
       
   292   KlassSizeStats sz, sz_sum;
       
   293   int i;
       
   294   julong *col_table = (julong*)(&sz);
       
   295   julong *colsum_table = (julong*)(&sz_sum);
       
   296   int width_table[KlassSizeStats::_num_columns];
       
   297   bool selected[KlassSizeStats::_num_columns];
       
   298 
       
   299   _selected_columns = columns;
       
   300 
       
   301   memset(&sz_sum, 0, sizeof(sz_sum));
       
   302   for (int c=0; c<KlassSizeStats::_num_columns; c++) {
       
   303     selected[c] = is_selected(name_table[c]);
       
   304   }
       
   305 
       
   306   for(i=0; i < elements()->length(); i++) {
       
   307     elements()->at(i)->set_index(i+1);
       
   308   }
       
   309 
       
   310   for (int pass=1; pass<=2; pass++) {
       
   311     if (pass == 2) {
       
   312       print_title(st, csv_format, selected, width_table, name_table);
       
   313     }
       
   314     for(i=0; i < elements()->length(); i++) {
       
   315       KlassInfoEntry* e = (KlassInfoEntry*)elements()->at(i);
       
   316       const Klass* k = e->klass();
       
   317 
       
   318       memset(&sz, 0, sizeof(sz));
       
   319       sz._inst_count = e->count();
       
   320       sz._inst_bytes = HeapWordSize * e->words();
       
   321       k->collect_statistics(&sz);
       
   322       sz._total_bytes = sz._ro_bytes + sz._rw_bytes;
       
   323 
       
   324       if (pass == 1) {
       
   325         for (int c=0; c<KlassSizeStats::_num_columns; c++) {
       
   326           colsum_table[c] += col_table[c];
       
   327         }
       
   328       } else {
       
   329         int super_index = -1;
       
   330         if (k->oop_is_instance()) {
       
   331           Klass* super = ((InstanceKlass*)k)->java_super();
       
   332           if (super) {
       
   333             KlassInfoEntry* super_e = _cit->lookup(super);
       
   334             if (super_e) {
       
   335               super_index = super_e->index();
       
   336             }
       
   337           }
       
   338         }
       
   339 
       
   340         if (csv_format) {
       
   341           st->print("%d,%d", e->index(), super_index);
       
   342           for (int c=0; c<KlassSizeStats::_num_columns; c++) {
       
   343             if (selected[c]) {st->print("," JULONG_FORMAT, col_table[c]);}
       
   344           }
       
   345           st->print(",%s",e->name());
       
   346         } else {
       
   347           st->print("%5d %5d", e->index(), super_index);
       
   348           for (int c=0; c<KlassSizeStats::_num_columns; c++) {
       
   349             if (selected[c]) {print_julong(st, width_table[c], col_table[c]);}
       
   350           }
       
   351           st->print(" %s", e->name());
       
   352         }
       
   353         if (is_selected("ClassLoader")) {
       
   354           ClassLoaderData* loader_data = k->class_loader_data();
       
   355           st->print(",");
       
   356           loader_data->print_value_on(st);
       
   357         }
       
   358         st->cr();
       
   359       }
       
   360     }
       
   361 
       
   362     if (pass == 1) {
       
   363       for (int c=0; c<KlassSizeStats::_num_columns; c++) {
       
   364         width_table[c] = col_width(colsum_table[c], name_table[c]);
       
   365       }
       
   366     }
       
   367   }
       
   368 
       
   369   sz_sum._inst_size = 0;
       
   370 
       
   371   if (csv_format) {
       
   372     st->print(",");
       
   373     for (int c=0; c<KlassSizeStats::_num_columns; c++) {
       
   374       if (selected[c]) {st->print("," JULONG_FORMAT, colsum_table[c]);}
       
   375     }
       
   376   } else {
       
   377     st->print("           ");
       
   378     for (int c=0; c<KlassSizeStats::_num_columns; c++) {
       
   379       if (selected[c]) {print_julong(st, width_table[c], colsum_table[c]);}
       
   380     }
       
   381     st->print(" Total");
       
   382     if (sz_sum._total_bytes > 0) {
       
   383       st->cr();
       
   384       st->print("           ");
       
   385       for (int c=0; c<KlassSizeStats::_num_columns; c++) {
       
   386         if (selected[c]) {
       
   387           switch (c) {
       
   388           case KlassSizeStats::_index_inst_size:
       
   389           case KlassSizeStats::_index_inst_count:
       
   390           case KlassSizeStats::_index_method_count:
       
   391             st->print(str_fmt(width_table[c]), "-");
       
   392             break;
       
   393           default:
       
   394             {
       
   395               double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes;
       
   396               st->print(perc_fmt(width_table[c]), perc);
       
   397             }
       
   398           }
       
   399         }
       
   400       }
       
   401     }
       
   402   }
       
   403   st->cr();
       
   404 
       
   405   if (!csv_format) {
       
   406     print_title(st, csv_format, selected, width_table, name_table);
       
   407   }
       
   408 }
       
   409 
       
   410 julong KlassInfoHisto::annotations_bytes(Array<AnnotationArray*>* p) const {
       
   411   julong bytes = 0;
       
   412   if (p != NULL) {
       
   413     for (int i = 0; i < p->length(); i++) {
       
   414       bytes += count_bytes_array(p->at(i));
       
   415     }
       
   416     bytes += count_bytes_array(p);
       
   417   }
       
   418   return bytes;
       
   419 }
       
   420 
       
   421 void KlassInfoHisto::print_histo_on(outputStream* st, bool print_stats,
       
   422                                     bool csv_format, const char *columns) {
       
   423   if (print_stats) {
       
   424     print_class_stats(st, csv_format, columns);
       
   425   } else {
       
   426     st->print_cr("%s",title());
       
   427     print_elements(st);
       
   428   }
   202 }
   429 }
   203 
   430 
   204 class HistoClosure : public KlassInfoClosure {
   431 class HistoClosure : public KlassInfoClosure {
   205  private:
   432  private:
   206   KlassInfoHisto* _cih;
   433   KlassInfoHisto* _cih;
   234   // Get some random number for ref (the hash key)
   461   // Get some random number for ref (the hash key)
   235   HeapWord* ref = (HeapWord*) Universe::boolArrayKlassObj();
   462   HeapWord* ref = (HeapWord*) Universe::boolArrayKlassObj();
   236   CollectedHeap* heap = Universe::heap();
   463   CollectedHeap* heap = Universe::heap();
   237   bool is_shared_heap = false;
   464   bool is_shared_heap = false;
   238 
   465 
       
   466   if (_print_help) {
       
   467     for (int c=0; c<KlassSizeStats::_num_columns; c++) {
       
   468       st->print("%s:\n\t", name_table[c]);
       
   469       const int max_col = 60;
       
   470       int col = 0;
       
   471       for (const char *p = help_table[c]; *p; p++,col++) {
       
   472         if (col >= max_col && *p == ' ') {
       
   473           st->print("\n\t");
       
   474           col = 0;
       
   475         } else {
       
   476           st->print("%c", *p);
       
   477         }
       
   478       }
       
   479       st->print_cr(".\n");
       
   480     }
       
   481     return;
       
   482   }
       
   483 
   239   // Collect klass instance info
   484   // Collect klass instance info
   240   KlassInfoTable cit(KlassInfoTable::cit_size, ref);
   485   KlassInfoTable cit(KlassInfoTable::cit_size, ref, _print_class_stats);
   241   if (!cit.allocation_failed()) {
   486   if (!cit.allocation_failed()) {
   242     // Iterate over objects in the heap
   487     // Iterate over objects in the heap
   243     RecordInstanceClosure ric(&cit);
   488     RecordInstanceClosure ric(&cit);
   244     Universe::heap()->object_iterate(&ric);
   489     Universe::heap()->object_iterate(&ric);
   245 
   490 
   250       st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
   495       st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
   251                    " total instances in data below",
   496                    " total instances in data below",
   252                    missed_count);
   497                    missed_count);
   253     }
   498     }
   254     // Sort and print klass instance info
   499     // Sort and print klass instance info
   255     KlassInfoHisto histo("\n"
   500     const char *title = "\n"
   256                      " num     #instances         #bytes  class name\n"
   501               " num     #instances         #bytes  class name\n"
   257                      "----------------------------------------------",
   502               "----------------------------------------------";
   258                      KlassInfoHisto::histo_initial_size);
   503     KlassInfoHisto histo(&cit, title, KlassInfoHisto::histo_initial_size);
   259     HistoClosure hc(&histo);
   504     HistoClosure hc(&histo);
   260     cit.iterate(&hc);
   505     cit.iterate(&hc);
   261     histo.sort();
   506     histo.sort();
   262     histo.print_on(st);
   507     histo.print_histo_on(st, _print_class_stats, _csv_format, _columns);
   263   } else {
   508   } else {
   264     st->print_cr("WARNING: Ran out of C-heap; histogram not generated");
   509     st->print_cr("WARNING: Ran out of C-heap; histogram not generated");
   265   }
   510   }
   266   st->flush();
   511   st->flush();
   267 
   512