1 /*
2 * Copyright (c) 2002, 2014, 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 "classfile/classLoaderData.hpp"
27 #include "gc_interface/collectedHeap.hpp"
28 #include "memory/genCollectedHeap.hpp"
29 #include "memory/heapInspection.hpp"
30 #include "memory/resourceArea.hpp"
31 #include "runtime/os.hpp"
32 #include "utilities/globalDefinitions.hpp"
33 #include "utilities/macros.hpp"
34 #if INCLUDE_ALL_GCS
35 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
36 #endif // INCLUDE_ALL_GCS
37
38 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
39
40 // HeapInspection
41
42 int KlassInfoEntry::compare(KlassInfoEntry* e1, KlassInfoEntry* e2) {
43 if(e1->_instance_words > e2->_instance_words) {
44 return -1;
45 } else if(e1->_instance_words < e2->_instance_words) {
46 return 1;
47 }
48 // Sort alphabetically, note 'Z' < '[' < 'a', but it's better to group
49 // the array classes before all the instance classes.
50 ResourceMark rm;
51 const char* name1 = e1->klass()->external_name();
52 const char* name2 = e2->klass()->external_name();
53 bool d1 = (name1[0] == '[');
54 bool d2 = (name2[0] == '[');
55 if (d1 && !d2) {
56 return -1;
57 } else if (d2 && !d1) {
58 return 1;
59 } else {
60 return strcmp(name1, name2);
61 }
112 elt = elt->next();
113 }
114 }
115
116 void KlassInfoBucket::empty() {
117 KlassInfoEntry* elt = _list;
118 _list = NULL;
119 while (elt != NULL) {
120 KlassInfoEntry* next = elt->next();
121 delete elt;
122 elt = next;
123 }
124 }
125
126 void KlassInfoTable::AllClassesFinder::do_klass(Klass* k) {
127 // This has the SIDE EFFECT of creating a KlassInfoEntry
128 // for <k>, if one doesn't exist yet.
129 _table->lookup(k);
130 }
131
132 KlassInfoTable::KlassInfoTable(bool need_class_stats) {
133 _size_of_instances_in_words = 0;
134 _size = 0;
135 _ref = (HeapWord*) Universe::boolArrayKlassObj();
136 _buckets =
137 (KlassInfoBucket*) AllocateHeap(sizeof(KlassInfoBucket) * _num_buckets,
138 mtInternal, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
139 if (_buckets != NULL) {
140 _size = _num_buckets;
141 for (int index = 0; index < _size; index++) {
142 _buckets[index].initialize();
143 }
144 if (need_class_stats) {
145 AllClassesFinder finder(this);
146 ClassLoaderDataGraph::classes_do(&finder);
147 }
148 }
149 }
150
151 KlassInfoTable::~KlassInfoTable() {
152 if (_buckets != NULL) {
153 for (int index = 0; index < _size; index++) {
154 _buckets[index].empty();
155 }
156 FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets);
157 _size = 0;
158 }
159 }
160
161 uint KlassInfoTable::hash(const Klass* p) {
162 return (uint)(((uintptr_t)p - (uintptr_t)_ref) >> 2);
163 }
164
282 if (selected[c]) {st->print(",%s", name_table[c]);}
283 }
284 st->print(",ClassName");
285 } else {
286 st->print("Index Super");
287 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
288 PRAGMA_DIAG_PUSH
289 PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
290 if (selected[c]) {st->print(str_fmt(width_table[c]), name_table[c]);}
291 PRAGMA_DIAG_POP
292 }
293 st->print(" ClassName");
294 }
295
296 if (is_selected("ClassLoader")) {
297 st->print(",ClassLoader");
298 }
299 st->cr();
300 }
301
302 void KlassInfoHisto::print_class_stats(outputStream* st,
303 bool csv_format, const char *columns) {
304 ResourceMark rm;
305 KlassSizeStats sz, sz_sum;
306 int i;
307 julong *col_table = (julong*)(&sz);
308 julong *colsum_table = (julong*)(&sz_sum);
309 int width_table[KlassSizeStats::_num_columns];
310 bool selected[KlassSizeStats::_num_columns];
311
312 _selected_columns = columns;
313
314 memset(&sz_sum, 0, sizeof(sz_sum));
315 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
316 selected[c] = is_selected(name_table[c]);
317 }
318
319 for(i=0; i < elements()->length(); i++) {
320 elements()->at(i)->set_index(i+1);
321 }
322
323 for (int pass=1; pass<=2; pass++) {
324 if (pass == 2) {
325 print_title(st, csv_format, selected, width_table, name_table);
326 }
327 for(i=0; i < elements()->length(); i++) {
328 KlassInfoEntry* e = (KlassInfoEntry*)elements()->at(i);
329 const Klass* k = e->klass();
330
331 memset(&sz, 0, sizeof(sz));
332 sz._inst_count = e->count();
333 sz._inst_bytes = HeapWordSize * e->words();
334 k->collect_statistics(&sz);
335 sz._total_bytes = sz._ro_bytes + sz._rw_bytes;
336
337 if (pass == 1) {
338 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
339 colsum_table[c] += col_table[c];
340 }
341 } else {
342 int super_index = -1;
343 if (k->oop_is_instance()) {
344 Klass* super = ((InstanceKlass*)k)->java_super();
345 if (super) {
346 KlassInfoEntry* super_e = _cit->lookup(super);
347 if (super_e) {
348 super_index = super_e->index();
349 }
350 }
351 }
352
353 if (csv_format) {
354 st->print("%d,%d", e->index(), super_index);
355 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
356 if (selected[c]) {st->print("," JULONG_FORMAT, col_table[c]);}
357 }
358 st->print(",%s",e->name());
359 } else {
360 st->print("%5d %5d", e->index(), super_index);
361 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
362 if (selected[c]) {print_julong(st, width_table[c], col_table[c]);}
363 }
364 st->print(" %s", e->name());
365 }
366 if (is_selected("ClassLoader")) {
367 ClassLoaderData* loader_data = k->class_loader_data();
368 st->print(",");
369 loader_data->print_value_on(st);
370 }
371 st->cr();
372 }
373 }
374
375 if (pass == 1) {
376 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
377 width_table[c] = col_width(colsum_table[c], name_table[c]);
378 }
379 }
380 }
381
382 sz_sum._inst_size = 0;
383
384 if (csv_format) {
385 st->print(",");
386 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
387 if (selected[c]) {st->print("," JULONG_FORMAT, colsum_table[c]);}
388 }
389 } else {
390 st->print(" ");
391 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
392 if (selected[c]) {print_julong(st, width_table[c], colsum_table[c]);}
393 }
394 st->print(" Total");
395 if (sz_sum._total_bytes > 0) {
396 st->cr();
397 st->print(" ");
398 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
399 if (selected[c]) {
400 switch (c) {
401 case KlassSizeStats::_index_inst_size:
402 case KlassSizeStats::_index_inst_count:
403 case KlassSizeStats::_index_method_count:
497 if (_print_help) {
498 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
499 st->print("%s:\n\t", name_table[c]);
500 const int max_col = 60;
501 int col = 0;
502 for (const char *p = help_table[c]; *p; p++,col++) {
503 if (col >= max_col && *p == ' ') {
504 st->print("\n\t");
505 col = 0;
506 } else {
507 st->print("%c", *p);
508 }
509 }
510 st->print_cr(".\n");
511 }
512 return;
513 }
514
515 KlassInfoTable cit(_print_class_stats);
516 if (!cit.allocation_failed()) {
517 size_t missed_count = populate_table(&cit);
518 if (missed_count != 0) {
519 st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
520 " total instances in data below",
521 missed_count);
522 }
523
524 // Sort and print klass instance info
525 const char *title = "\n"
526 " num #instances #bytes class name\n"
527 "----------------------------------------------";
528 KlassInfoHisto histo(&cit, title);
529 HistoClosure hc(&histo);
530
531 cit.iterate(&hc);
532
533 histo.sort();
534 histo.print_histo_on(st, _print_class_stats, _csv_format, _columns);
535 } else {
536 st->print_cr("WARNING: Ran out of C-heap; histogram not generated");
|
1 /*
2 * Copyright (c) 2002, 2015, 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 "classfile/classLoaderData.hpp"
27 #include "gc_interface/collectedHeap.hpp"
28 #include "memory/genCollectedHeap.hpp"
29 #include "memory/heapInspection.hpp"
30 #include "memory/resourceArea.hpp"
31 #include "runtime/os.hpp"
32 #include "utilities/globalDefinitions.hpp"
33 #include "utilities/macros.hpp"
34 #if INCLUDE_ALL_GCS
35 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
36 #endif // INCLUDE_ALL_GCS
37
38 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
39
40 // HeapInspection
41
42 inline KlassInfoEntry::~KlassInfoEntry() {
43 if (_subclasses != NULL) {
44 delete _subclasses;
45 }
46 }
47
48 inline void KlassInfoEntry::add_subclass(KlassInfoEntry* cie) {
49 if (_subclasses == NULL) {
50 _subclasses = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(4, true);
51 }
52 _subclasses->append(cie);
53 }
54
55 int KlassInfoEntry::compare(KlassInfoEntry* e1, KlassInfoEntry* e2) {
56 if(e1->_instance_words > e2->_instance_words) {
57 return -1;
58 } else if(e1->_instance_words < e2->_instance_words) {
59 return 1;
60 }
61 // Sort alphabetically, note 'Z' < '[' < 'a', but it's better to group
62 // the array classes before all the instance classes.
63 ResourceMark rm;
64 const char* name1 = e1->klass()->external_name();
65 const char* name2 = e2->klass()->external_name();
66 bool d1 = (name1[0] == '[');
67 bool d2 = (name2[0] == '[');
68 if (d1 && !d2) {
69 return -1;
70 } else if (d2 && !d1) {
71 return 1;
72 } else {
73 return strcmp(name1, name2);
74 }
125 elt = elt->next();
126 }
127 }
128
129 void KlassInfoBucket::empty() {
130 KlassInfoEntry* elt = _list;
131 _list = NULL;
132 while (elt != NULL) {
133 KlassInfoEntry* next = elt->next();
134 delete elt;
135 elt = next;
136 }
137 }
138
139 void KlassInfoTable::AllClassesFinder::do_klass(Klass* k) {
140 // This has the SIDE EFFECT of creating a KlassInfoEntry
141 // for <k>, if one doesn't exist yet.
142 _table->lookup(k);
143 }
144
145 KlassInfoTable::KlassInfoTable(bool add_all_classes) {
146 _size_of_instances_in_words = 0;
147 _size = 0;
148 _ref = (HeapWord*) Universe::boolArrayKlassObj();
149 _buckets =
150 (KlassInfoBucket*) AllocateHeap(sizeof(KlassInfoBucket) * _num_buckets,
151 mtInternal, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
152 if (_buckets != NULL) {
153 _size = _num_buckets;
154 for (int index = 0; index < _size; index++) {
155 _buckets[index].initialize();
156 }
157 if (add_all_classes) {
158 AllClassesFinder finder(this);
159 ClassLoaderDataGraph::classes_do(&finder);
160 }
161 }
162 }
163
164 KlassInfoTable::~KlassInfoTable() {
165 if (_buckets != NULL) {
166 for (int index = 0; index < _size; index++) {
167 _buckets[index].empty();
168 }
169 FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets);
170 _size = 0;
171 }
172 }
173
174 uint KlassInfoTable::hash(const Klass* p) {
175 return (uint)(((uintptr_t)p - (uintptr_t)_ref) >> 2);
176 }
177
295 if (selected[c]) {st->print(",%s", name_table[c]);}
296 }
297 st->print(",ClassName");
298 } else {
299 st->print("Index Super");
300 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
301 PRAGMA_DIAG_PUSH
302 PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
303 if (selected[c]) {st->print(str_fmt(width_table[c]), name_table[c]);}
304 PRAGMA_DIAG_POP
305 }
306 st->print(" ClassName");
307 }
308
309 if (is_selected("ClassLoader")) {
310 st->print(",ClassLoader");
311 }
312 st->cr();
313 }
314
315 class HierarchyClosure : public KlassInfoClosure {
316 private:
317 GrowableArray<KlassInfoEntry*> *_elements;
318 public:
319 HierarchyClosure(GrowableArray<KlassInfoEntry*> *_elements) : _elements(_elements) {}
320
321 void do_cinfo(KlassInfoEntry* cie) {
322 // ignore array classes
323 if (cie->klass()->oop_is_instance()) {
324 _elements->append(cie);
325 }
326 }
327 };
328
329 void KlassHierarchy::print_class_hierarchy(outputStream* st, bool print_interfaces,
330 bool print_subclasses, char* classname) {
331 ResourceMark rm;
332 Stack <KlassInfoEntry*, mtClass> class_stack;
333 GrowableArray<KlassInfoEntry*> elements;
334
335 // Add all classes to the KlassInfoTable, which allows for quick lookup.
336 // A KlassInfoEntry will be created for each class.
337 KlassInfoTable cit(true);
338 if (cit.allocation_failed()) {
339 st->print_cr("WARNING: Ran out of C-heap; hierarchy not generated");
340 return;
341 }
342
343 // Add all created KlassInfoEntry instances to the elements array for easy
344 // iteration, and to allow each KlassInfoEntry instance to have a unique index.
345 HierarchyClosure hc(&elements);
346 cit.iterate(&hc);
347
348 for(int i = 0; i < elements.length(); i++) {
349 KlassInfoEntry* cie = elements.at(i);
350 const InstanceKlass* k = (InstanceKlass*)cie->klass();
351 Klass* super = ((InstanceKlass*)k)->java_super();
352
353 // Set the index for the class.
354 cie->set_index(i + 1);
355
356 // Add the class to the subclass array of its superclass.
357 if (super != NULL) {
358 KlassInfoEntry* super_cie = cit.lookup(super);
359 assert(super_cie != NULL, "could not lookup superclass");
360 super_cie->add_subclass(cie);
361 }
362 }
363
364 // Set the do_print flag for each class that should be printed.
365 for(int i = 0; i < elements.length(); i++) {
366 KlassInfoEntry* cie = elements.at(i);
367 if (classname == NULL) {
368 // We are printing all classes.
369 cie->set_do_print(true);
370 } else {
371 // We are only printing the hierarchy of a specific class.
372 if (strcmp(classname, cie->klass()->external_name()) == 0) {
373 KlassHierarchy::set_do_print_for_class_hierarchy(cie, &cit, print_subclasses);
374 }
375 }
376 }
377
378 // Now we do a depth first traversal of the class hierachry. The class_stack will
379 // maintain the list of classes we still need to process. Start things off
380 // by priming it with java.lang.Object.
381 KlassInfoEntry* jlo_cie = cit.lookup(SystemDictionary::Object_klass());
382 assert(jlo_cie != NULL, "could not lookup java.lang.Object");
383 class_stack.push(jlo_cie);
384
385 // Repeatedly pop the top item off the stack, print its class info,
386 // and push all of its subclasses on to the stack. Do this until there
387 // are no classes left on the stack.
388 while (!class_stack.is_empty()) {
389 KlassInfoEntry* curr_cie = class_stack.pop();
390 if (curr_cie->do_print()) {
391 print_class(st, curr_cie, print_interfaces);
392 if (curr_cie->subclasses() != NULL) {
393 // Current class has subclasses, so push all of them onto the stack.
394 for (int i = 0; i < curr_cie->subclasses()->length(); i++) {
395 KlassInfoEntry* cie = curr_cie->subclasses()->at(i);
396 if (cie->do_print()) {
397 class_stack.push(cie);
398 }
399 }
400 }
401 }
402 }
403
404 st->flush();
405 }
406
407 // Sets the do_print flag for every superclass and subclass of the specified class.
408 void KlassHierarchy::set_do_print_for_class_hierarchy(KlassInfoEntry* cie, KlassInfoTable* cit,
409 bool print_subclasses) {
410 // Set do_print for all superclasses of this class.
411 Klass* super = ((InstanceKlass*)cie->klass())->java_super();
412 while (super != NULL) {
413 KlassInfoEntry* super_cie = cit->lookup(super);
414 super_cie->set_do_print(true);
415 super = super->super();
416 }
417
418 // Set do_print for this class and all of its subclasses.
419 Stack <KlassInfoEntry*, mtClass> class_stack;
420 class_stack.push(cie);
421 while (!class_stack.is_empty()) {
422 KlassInfoEntry* curr_cie = class_stack.pop();
423 curr_cie->set_do_print(true);
424 if (print_subclasses && curr_cie->subclasses() != NULL) {
425 // Current class has subclasses, so push all of them onto the stack.
426 for (int i = 0; i < curr_cie->subclasses()->length(); i++) {
427 KlassInfoEntry* cie = curr_cie->subclasses()->at(i);
428 class_stack.push(cie);
429 }
430 }
431 }
432 }
433
434 static void print_indent(outputStream* st, int indent) {
435 while (indent != 0) {
436 st->print("|");
437 indent--;
438 if (indent != 0) {
439 st->print(" ");
440 }
441 }
442 }
443
444 // Print the class name and its unique ClassLoader identifer.
445 static void print_classname(outputStream* st, Klass* klass) {
446 oop loader_oop = klass->class_loader_data()->class_loader();
447 st->print("%s/", klass->external_name());
448 if (loader_oop == NULL) {
449 st->print("null");
450 } else {
451 st->print(INTPTR_FORMAT, loader_oop->klass());
452 }
453 }
454
455 static void print_interface(outputStream* st, Klass* intf_klass, const char* intf_type, int indent) {
456 print_indent(st, indent);
457 st->print(" implements ");
458 print_classname(st, intf_klass);
459 st->print(" (%s intf)\n", intf_type);
460 }
461
462 void KlassHierarchy::print_class(outputStream* st, KlassInfoEntry* cie, bool print_interfaces) {
463 ResourceMark rm;
464 InstanceKlass* klass = (InstanceKlass*)cie->klass();
465 int indent = 0;
466
467 // Print indentation with proper indicators of superclass.
468 Klass* super = klass->super();
469 while (super != NULL) {
470 super = super->super();
471 indent++;
472 }
473 print_indent(st, indent);
474 if (indent != 0) st->print("--");
475
476 // Print the class name, its unique ClassLoader identifer, and if it is an interface.
477 print_classname(st, klass);
478 if (klass->is_interface()) {
479 st->print(" (intf)");
480 }
481 st->print("\n");
482
483 // Print any interfaces the class has.
484 if (print_interfaces) {
485 Array<Klass*>* local_intfs = klass->local_interfaces();
486 Array<Klass*>* trans_intfs = klass->transitive_interfaces();
487 for (int i = 0; i < local_intfs->length(); i++) {
488 print_interface(st, local_intfs->at(i), "declared", indent);
489 }
490 for (int i = 0; i < trans_intfs->length(); i++) {
491 Klass* trans_interface = trans_intfs->at(i);
492 // Only print transitive interfaces if they are not also declared.
493 if (!local_intfs->contains(trans_interface)) {
494 print_interface(st, trans_interface, "transitive", indent);
495 }
496 }
497 }
498 }
499
500 void KlassInfoHisto::print_class_stats(outputStream* st,
501 bool csv_format, const char *columns) {
502 KlassSizeStats sz, sz_sum;
503 int i;
504 julong *col_table = (julong*)(&sz);
505 julong *colsum_table = (julong*)(&sz_sum);
506 int width_table[KlassSizeStats::_num_columns];
507 bool selected[KlassSizeStats::_num_columns];
508
509 _selected_columns = columns;
510
511 memset(&sz_sum, 0, sizeof(sz_sum));
512 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
513 selected[c] = is_selected(name_table[c]);
514 }
515
516 for(i=0; i < elements()->length(); i++) {
517 elements()->at(i)->set_index(i+1);
518 }
519
520 // First iteration is for accumulating stats totals in colsum_table[].
521 // Second iteration is for printing stats for each class.
522 for (int pass=1; pass<=2; pass++) {
523 if (pass == 2) {
524 print_title(st, csv_format, selected, width_table, name_table);
525 }
526 for(i=0; i < elements()->length(); i++) {
527 KlassInfoEntry* e = (KlassInfoEntry*)elements()->at(i);
528 const Klass* k = e->klass();
529
530 // Get the stats for this class.
531 memset(&sz, 0, sizeof(sz));
532 sz._inst_count = e->count();
533 sz._inst_bytes = HeapWordSize * e->words();
534 k->collect_statistics(&sz);
535 sz._total_bytes = sz._ro_bytes + sz._rw_bytes;
536
537 if (pass == 1) {
538 // Add the stats for this class to the overall totals.
539 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
540 colsum_table[c] += col_table[c];
541 }
542 } else {
543 int super_index = -1;
544 // Print the stats for this class.
545 if (k->oop_is_instance()) {
546 Klass* super = ((InstanceKlass*)k)->java_super();
547 if (super) {
548 KlassInfoEntry* super_e = _cit->lookup(super);
549 if (super_e) {
550 super_index = super_e->index();
551 }
552 }
553 }
554
555 if (csv_format) {
556 st->print("%d,%d", e->index(), super_index);
557 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
558 if (selected[c]) {st->print("," JULONG_FORMAT, col_table[c]);}
559 }
560 st->print(",%s",e->name());
561 } else {
562 st->print("%5d %5d", e->index(), super_index);
563 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
564 if (selected[c]) {print_julong(st, width_table[c], col_table[c]);}
565 }
566 st->print(" %s", e->name());
567 }
568 if (is_selected("ClassLoader")) {
569 ClassLoaderData* loader_data = k->class_loader_data();
570 st->print(",");
571 loader_data->print_value_on(st);
572 }
573 st->cr();
574 }
575 }
576
577 if (pass == 1) {
578 // Calculate the minimum width needed for the column by accounting for the
579 // column header width and the width of the largest value in the column.
580 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
581 width_table[c] = col_width(colsum_table[c], name_table[c]);
582 }
583 }
584 }
585
586 sz_sum._inst_size = 0;
587
588 // Print the column totals.
589 if (csv_format) {
590 st->print(",");
591 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
592 if (selected[c]) {st->print("," JULONG_FORMAT, colsum_table[c]);}
593 }
594 } else {
595 st->print(" ");
596 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
597 if (selected[c]) {print_julong(st, width_table[c], colsum_table[c]);}
598 }
599 st->print(" Total");
600 if (sz_sum._total_bytes > 0) {
601 st->cr();
602 st->print(" ");
603 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
604 if (selected[c]) {
605 switch (c) {
606 case KlassSizeStats::_index_inst_size:
607 case KlassSizeStats::_index_inst_count:
608 case KlassSizeStats::_index_method_count:
702 if (_print_help) {
703 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
704 st->print("%s:\n\t", name_table[c]);
705 const int max_col = 60;
706 int col = 0;
707 for (const char *p = help_table[c]; *p; p++,col++) {
708 if (col >= max_col && *p == ' ') {
709 st->print("\n\t");
710 col = 0;
711 } else {
712 st->print("%c", *p);
713 }
714 }
715 st->print_cr(".\n");
716 }
717 return;
718 }
719
720 KlassInfoTable cit(_print_class_stats);
721 if (!cit.allocation_failed()) {
722 // populate table with object allocation info
723 size_t missed_count = populate_table(&cit);
724 if (missed_count != 0) {
725 st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
726 " total instances in data below",
727 missed_count);
728 }
729
730 // Sort and print klass instance info
731 const char *title = "\n"
732 " num #instances #bytes class name\n"
733 "----------------------------------------------";
734 KlassInfoHisto histo(&cit, title);
735 HistoClosure hc(&histo);
736
737 cit.iterate(&hc);
738
739 histo.sort();
740 histo.print_histo_on(st, _print_class_stats, _csv_format, _columns);
741 } else {
742 st->print_cr("WARNING: Ran out of C-heap; histogram not generated");
|