1 /* |
1 /* |
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1997, 2012, 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. |
23 */ |
23 */ |
24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" |
26 #include "classfile/systemDictionary.hpp" |
27 #include "gc_interface/collectedHeap.inline.hpp" |
27 #include "gc_interface/collectedHeap.inline.hpp" |
28 #include "memory/permGen.hpp" |
|
29 #include "memory/resourceArea.hpp" |
28 #include "memory/resourceArea.hpp" |
30 #include "memory/space.hpp" |
29 #include "memory/space.hpp" |
31 #include "oops/oop.inline.hpp" |
30 #include "oops/oop.inline.hpp" |
32 #include "oops/oop.inline2.hpp" |
31 #include "oops/oop.inline2.hpp" |
33 #include "runtime/aprofiler.hpp" |
32 #include "runtime/aprofiler.hpp" |
34 |
33 |
35 |
34 |
36 bool AllocationProfiler::_active = false; |
35 bool AllocationProfiler::_active = false; |
37 GrowableArray<klassOop>* AllocationProfiler::_print_array = NULL; |
36 GrowableArray<Klass*>* AllocationProfiler::_print_array = NULL; |
38 |
37 |
39 |
38 |
40 class AllocProfClosure : public ObjectClosure { |
39 class AllocProfClosure : public ObjectClosure { |
41 public: |
40 public: |
42 void do_object(oop obj) { |
41 void do_object(oop obj) { |
43 Klass* k = obj->blueprint(); |
42 Klass* k = obj->klass(); |
44 k->set_alloc_count(k->alloc_count() + 1); |
43 k->set_alloc_count(k->alloc_count() + 1); |
45 k->set_alloc_size(k->alloc_size() + obj->size()); |
44 k->set_alloc_size(k->alloc_size() + obj->size()); |
46 } |
45 } |
47 }; |
46 }; |
48 |
|
49 |
|
50 #ifndef PRODUCT |
|
51 |
|
52 class AllocProfResetClosure : public ObjectClosure { |
|
53 public: |
|
54 void do_object(oop obj) { |
|
55 if (obj->is_klass()) { |
|
56 Klass* k = Klass::cast(klassOop(obj)); |
|
57 k->set_alloc_count(0); |
|
58 k->set_alloc_size(0); |
|
59 } |
|
60 } |
|
61 }; |
|
62 |
|
63 #endif |
|
64 |
47 |
65 |
48 |
66 void AllocationProfiler::iterate_since_last_gc() { |
49 void AllocationProfiler::iterate_since_last_gc() { |
67 if (is_active()) { |
50 if (is_active()) { |
68 AllocProfClosure blk; |
51 AllocProfClosure blk; |
80 void AllocationProfiler::disengage() { |
63 void AllocationProfiler::disengage() { |
81 _active = false; |
64 _active = false; |
82 } |
65 } |
83 |
66 |
84 |
67 |
85 void AllocationProfiler::add_class_to_array(klassOop k) { |
68 void AllocationProfiler::add_class_to_array(Klass* k) { |
86 _print_array->append(k); |
69 _print_array->append(k); |
87 } |
70 } |
88 |
71 |
89 |
72 |
90 void AllocationProfiler::add_classes_to_array(klassOop k) { |
73 void AllocationProfiler::add_classes_to_array(Klass* k) { |
91 // Iterate over klass and all array klasses for klass |
74 // Iterate over klass and all array klasses for klass |
92 k->klass_part()->with_array_klasses_do(&AllocationProfiler::add_class_to_array); |
75 k->with_array_klasses_do(&AllocationProfiler::add_class_to_array); |
93 } |
76 } |
94 |
77 |
95 |
78 |
96 int AllocationProfiler::compare_classes(klassOop* k1, klassOop* k2) { |
79 int AllocationProfiler::compare_classes(Klass** k1, Klass** k2) { |
97 // Sort by total allocation size |
80 // Sort by total allocation size |
98 return (*k2)->klass_part()->alloc_size() - (*k1)->klass_part()->alloc_size(); |
81 return (*k2)->alloc_size() - (*k1)->alloc_size(); |
99 } |
82 } |
100 |
83 |
101 |
84 |
102 int AllocationProfiler::average(size_t alloc_size, int alloc_count) { |
85 int AllocationProfiler::average(size_t alloc_size, int alloc_count) { |
103 return (int) ((double) (alloc_size * BytesPerWord) / MAX2(alloc_count, 1) + 0.5); |
86 return (int) ((double) (alloc_size * BytesPerWord) / MAX2(alloc_count, 1) + 0.5); |
111 "__Average" |
94 "__Average" |
112 "__Class________________"); |
95 "__Class________________"); |
113 size_t total_alloc_size = 0; |
96 size_t total_alloc_size = 0; |
114 int total_alloc_count = 0; |
97 int total_alloc_count = 0; |
115 for (int index = 0; index < _print_array->length(); index++) { |
98 for (int index = 0; index < _print_array->length(); index++) { |
116 klassOop k = _print_array->at(index); |
99 Klass* k = _print_array->at(index); |
117 size_t alloc_size = k->klass_part()->alloc_size(); |
100 size_t alloc_size = k->alloc_size(); |
118 if (alloc_size > cutoff) { |
101 if (alloc_size > cutoff) { |
119 int alloc_count = k->klass_part()->alloc_count(); |
102 int alloc_count = k->alloc_count(); |
120 #ifdef PRODUCT |
103 #ifdef PRODUCT |
121 const char* name = k->klass_part()->external_name(); |
104 const char* name = k->external_name(); |
122 #else |
105 #else |
123 const char* name = k->klass_part()->internal_name(); |
106 const char* name = k->internal_name(); |
124 #endif |
107 #endif |
125 tty->print_cr("%20u %10u %8u %s", |
108 tty->print_cr("%20u %10u %8u %s", |
126 alloc_size * BytesPerWord, |
109 alloc_size * BytesPerWord, |
127 alloc_count, |
110 alloc_count, |
128 average(alloc_size, alloc_count), |
111 average(alloc_size, alloc_count), |
129 name); |
112 name); |
130 total_alloc_size += alloc_size; |
113 total_alloc_size += alloc_size; |
131 total_alloc_count += alloc_count; |
114 total_alloc_count += alloc_count; |
132 } |
115 } |
|
116 k->set_alloc_count(0); |
|
117 k->set_alloc_size(0); |
133 } |
118 } |
134 tty->print_cr("%20u %10u %8u --total--", |
119 tty->print_cr("%20u %10u %8u --total--", |
135 total_alloc_size * BytesPerWord, |
120 total_alloc_size * BytesPerWord, |
136 total_alloc_count, |
121 total_alloc_count, |
137 average(total_alloc_size, total_alloc_count)); |
122 average(total_alloc_size, total_alloc_count)); |
146 tty->cr(); |
131 tty->cr(); |
147 tty->print_cr("Allocation profile (sizes in bytes, cutoff = %ld bytes):", cutoff * BytesPerWord); |
132 tty->print_cr("Allocation profile (sizes in bytes, cutoff = %ld bytes):", cutoff * BytesPerWord); |
148 tty->cr(); |
133 tty->cr(); |
149 |
134 |
150 // Print regular instance klasses and basic type array klasses |
135 // Print regular instance klasses and basic type array klasses |
151 _print_array = new GrowableArray<klassOop>(SystemDictionary::number_of_classes()*2); |
136 _print_array = new GrowableArray<Klass*>(SystemDictionary::number_of_classes()*2); |
152 SystemDictionary::classes_do(&add_classes_to_array); |
137 SystemDictionary::classes_do(&add_classes_to_array); |
153 Universe::basic_type_classes_do(&add_classes_to_array); |
138 Universe::basic_type_classes_do(&add_classes_to_array); |
154 sort_and_print_array(cutoff); |
139 sort_and_print_array(cutoff); |
155 |
140 |
156 #ifndef PRODUCT |
141 // This used to print metadata in the permgen but since there isn't a permgen |
157 tty->print_cr("Allocation profile for system classes (sizes in bytes, cutoff = %d bytes):", cutoff * BytesPerWord); |
142 // anymore, it is not yet implemented. |
158 tty->cr(); |
|
159 |
|
160 // Print system klasses (methods, symbols, constant pools, etc.) |
|
161 _print_array = new GrowableArray<klassOop>(64); |
|
162 Universe::system_classes_do(&add_classes_to_array); |
|
163 sort_and_print_array(cutoff); |
|
164 |
|
165 tty->print_cr("Permanent generation dump (sizes in bytes, cutoff = %d bytes):", cutoff * BytesPerWord); |
|
166 tty->cr(); |
|
167 |
|
168 AllocProfResetClosure resetblk; |
|
169 Universe::heap()->permanent_object_iterate(&resetblk); |
|
170 AllocProfClosure blk; |
|
171 Universe::heap()->permanent_object_iterate(&blk); |
|
172 |
|
173 _print_array = new GrowableArray<klassOop>(SystemDictionary::number_of_classes()*2); |
|
174 SystemDictionary::classes_do(&add_classes_to_array); |
|
175 Universe::basic_type_classes_do(&add_classes_to_array); |
|
176 Universe::system_classes_do(&add_classes_to_array); |
|
177 sort_and_print_array(cutoff); |
|
178 #endif |
|
179 } |
143 } |