0
|
1 /*
|
|
2 * Copyright 1997-2002 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any questions.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 # include "incls/_precompiled.incl"
|
|
26 # include "incls/_aprofiler.cpp.incl"
|
|
27
|
|
28
|
|
29 bool AllocationProfiler::_active = false;
|
|
30 GrowableArray<klassOop>* AllocationProfiler::_print_array = NULL;
|
|
31
|
|
32
|
|
33 class AllocProfClosure : public ObjectClosure {
|
|
34 public:
|
|
35 void do_object(oop obj) {
|
|
36 Klass* k = obj->blueprint();
|
|
37 k->set_alloc_count(k->alloc_count() + 1);
|
|
38 k->set_alloc_size(k->alloc_size() + obj->size());
|
|
39 }
|
|
40 };
|
|
41
|
|
42
|
|
43 #ifndef PRODUCT
|
|
44
|
|
45 class AllocProfResetClosure : public ObjectClosure {
|
|
46 public:
|
|
47 void do_object(oop obj) {
|
|
48 if (obj->is_klass()) {
|
|
49 Klass* k = Klass::cast(klassOop(obj));
|
|
50 k->set_alloc_count(0);
|
|
51 k->set_alloc_size(0);
|
|
52 }
|
|
53 }
|
|
54 };
|
|
55
|
|
56 #endif
|
|
57
|
|
58
|
|
59 void AllocationProfiler::iterate_since_last_gc() {
|
|
60 if (is_active()) {
|
|
61 AllocProfClosure blk;
|
|
62 GenCollectedHeap* heap = GenCollectedHeap::heap();
|
|
63 heap->object_iterate_since_last_GC(&blk);
|
|
64 }
|
|
65 }
|
|
66
|
|
67
|
|
68 void AllocationProfiler::engage() {
|
|
69 _active = true;
|
|
70 }
|
|
71
|
|
72
|
|
73 void AllocationProfiler::disengage() {
|
|
74 _active = false;
|
|
75 }
|
|
76
|
|
77
|
|
78 void AllocationProfiler::add_class_to_array(klassOop k) {
|
|
79 _print_array->append(k);
|
|
80 }
|
|
81
|
|
82
|
|
83 void AllocationProfiler::add_classes_to_array(klassOop k) {
|
|
84 // Iterate over klass and all array klasses for klass
|
|
85 k->klass_part()->with_array_klasses_do(&AllocationProfiler::add_class_to_array);
|
|
86 }
|
|
87
|
|
88
|
|
89 int AllocationProfiler::compare_classes(klassOop* k1, klassOop* k2) {
|
|
90 // Sort by total allocation size
|
|
91 return (*k2)->klass_part()->alloc_size() - (*k1)->klass_part()->alloc_size();
|
|
92 }
|
|
93
|
|
94
|
|
95 int AllocationProfiler::average(size_t alloc_size, int alloc_count) {
|
|
96 return (int) ((double) (alloc_size * BytesPerWord) / MAX2(alloc_count, 1) + 0.5);
|
|
97 }
|
|
98
|
|
99
|
|
100 void AllocationProfiler::sort_and_print_array(size_t cutoff) {
|
|
101 _print_array->sort(&AllocationProfiler::compare_classes);
|
|
102 tty->print_cr("________________Size"
|
|
103 "__Instances"
|
|
104 "__Average"
|
|
105 "__Class________________");
|
|
106 size_t total_alloc_size = 0;
|
|
107 int total_alloc_count = 0;
|
|
108 for (int index = 0; index < _print_array->length(); index++) {
|
|
109 klassOop k = _print_array->at(index);
|
|
110 size_t alloc_size = k->klass_part()->alloc_size();
|
|
111 if (alloc_size > cutoff) {
|
|
112 int alloc_count = k->klass_part()->alloc_count();
|
|
113 #ifdef PRODUCT
|
|
114 const char* name = k->klass_part()->external_name();
|
|
115 #else
|
|
116 const char* name = k->klass_part()->internal_name();
|
|
117 #endif
|
|
118 tty->print_cr("%20u %10u %8u %s",
|
|
119 alloc_size * BytesPerWord,
|
|
120 alloc_count,
|
|
121 average(alloc_size, alloc_count),
|
|
122 name);
|
|
123 total_alloc_size += alloc_size;
|
|
124 total_alloc_count += alloc_count;
|
|
125 }
|
|
126 }
|
|
127 tty->print_cr("%20u %10u %8u --total--",
|
|
128 total_alloc_size * BytesPerWord,
|
|
129 total_alloc_count,
|
|
130 average(total_alloc_size, total_alloc_count));
|
|
131 tty->cr();
|
|
132 }
|
|
133
|
|
134
|
|
135 void AllocationProfiler::print(size_t cutoff) {
|
|
136 ResourceMark rm;
|
|
137 assert(!is_active(), "AllocationProfiler cannot be active while printing profile");
|
|
138
|
|
139 tty->cr();
|
|
140 tty->print_cr("Allocation profile (sizes in bytes, cutoff = %ld bytes):", cutoff * BytesPerWord);
|
|
141 tty->cr();
|
|
142
|
|
143 // Print regular instance klasses and basic type array klasses
|
|
144 _print_array = new GrowableArray<klassOop>(SystemDictionary::number_of_classes()*2);
|
|
145 SystemDictionary::classes_do(&add_classes_to_array);
|
|
146 Universe::basic_type_classes_do(&add_classes_to_array);
|
|
147 sort_and_print_array(cutoff);
|
|
148
|
|
149 #ifndef PRODUCT
|
|
150 tty->print_cr("Allocation profile for system classes (sizes in bytes, cutoff = %d bytes):", cutoff * BytesPerWord);
|
|
151 tty->cr();
|
|
152
|
|
153 // Print system klasses (methods, symbols, constant pools, etc.)
|
|
154 _print_array = new GrowableArray<klassOop>(64);
|
|
155 Universe::system_classes_do(&add_classes_to_array);
|
|
156 sort_and_print_array(cutoff);
|
|
157
|
|
158 tty->print_cr("Permanent generation dump (sizes in bytes, cutoff = %d bytes):", cutoff * BytesPerWord);
|
|
159 tty->cr();
|
|
160
|
|
161 AllocProfResetClosure resetblk;
|
|
162 Universe::heap()->permanent_object_iterate(&resetblk);
|
|
163 AllocProfClosure blk;
|
|
164 Universe::heap()->permanent_object_iterate(&blk);
|
|
165
|
|
166 _print_array = new GrowableArray<klassOop>(SystemDictionary::number_of_classes()*2);
|
|
167 SystemDictionary::classes_do(&add_classes_to_array);
|
|
168 Universe::basic_type_classes_do(&add_classes_to_array);
|
|
169 Universe::system_classes_do(&add_classes_to_array);
|
|
170 sort_and_print_array(cutoff);
|
|
171 #endif
|
|
172 }
|