Mercurial > hg > truffle
annotate src/share/vm/memory/heapInspection.hpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | 78bbf4d43a14 |
children | 52b4284cb496 |
rev | line source |
---|---|
0 | 1 /* |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12823
diff
changeset
|
2 * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
615
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
615
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
615
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_MEMORY_HEAPINSPECTION_HPP |
26 #define SHARE_VM_MEMORY_HEAPINSPECTION_HPP | |
27 | |
28 #include "memory/allocation.inline.hpp" | |
29 #include "oops/oop.inline.hpp" | |
7956 | 30 #include "oops/annotations.hpp" |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
6854
diff
changeset
|
31 #include "utilities/macros.hpp" |
1972 | 32 |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
33 #if INCLUDE_SERVICES |
0 | 34 |
35 | |
36 // HeapInspection | |
37 | |
38 // KlassInfoTable is a bucket hash table that | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
39 // maps Klass*s to extra information: |
0 | 40 // instance count and instance word size. |
41 // | |
42 // A KlassInfoBucket is the head of a link list | |
43 // of KlassInfoEntry's | |
44 // | |
45 // KlassInfoHisto is a growable array of pointers | |
46 // to KlassInfoEntry's and is used to sort | |
47 // the entries. | |
48 | |
7956 | 49 #define HEAP_INSPECTION_COLUMNS_DO(f) \ |
50 f(inst_size, InstSize, \ | |
51 "Size of each object instance of the Java class") \ | |
52 f(inst_count, InstCount, \ | |
53 "Number of object instances of the Java class") \ | |
54 f(inst_bytes, InstBytes, \ | |
55 "This is usually (InstSize * InstNum). The only exception is " \ | |
56 "java.lang.Class, whose InstBytes also includes the slots " \ | |
57 "used to store static fields. InstBytes is not counted in " \ | |
58 "ROAll, RWAll or Total") \ | |
59 f(mirror_bytes, Mirror, \ | |
60 "Size of the Klass::java_mirror() object") \ | |
61 f(klass_bytes, KlassBytes, \ | |
62 "Size of the InstanceKlass or ArrayKlass for this class. " \ | |
63 "Note that this includes VTab, ITab, OopMap") \ | |
64 f(secondary_supers_bytes, K_secondary_supers, \ | |
65 "Number of bytes used by the Klass::secondary_supers() array") \ | |
66 f(vtab_bytes, VTab, \ | |
67 "Size of the embedded vtable in InstanceKlass") \ | |
68 f(itab_bytes, ITab, \ | |
69 "Size of the embedded itable in InstanceKlass") \ | |
70 f(nonstatic_oopmap_bytes, OopMap, \ | |
71 "Size of the embedded nonstatic_oop_map in InstanceKlass") \ | |
72 f(methods_array_bytes, IK_methods, \ | |
73 "Number of bytes used by the InstanceKlass::methods() array") \ | |
74 f(method_ordering_bytes, IK_method_ordering, \ | |
75 "Number of bytes used by the InstanceKlass::method_ordering() array") \ | |
12823
ac9cb1d5a202
8009130: Lambda: Fix access controls, loader constraints.
acorn
parents:
12316
diff
changeset
|
76 f(default_methods_array_bytes, IK_default_methods, \ |
ac9cb1d5a202
8009130: Lambda: Fix access controls, loader constraints.
acorn
parents:
12316
diff
changeset
|
77 "Number of bytes used by the InstanceKlass::default_methods() array") \ |
ac9cb1d5a202
8009130: Lambda: Fix access controls, loader constraints.
acorn
parents:
12316
diff
changeset
|
78 f(default_vtable_indices_bytes, IK_default_vtable_indices, \ |
ac9cb1d5a202
8009130: Lambda: Fix access controls, loader constraints.
acorn
parents:
12316
diff
changeset
|
79 "Number of bytes used by the InstanceKlass::default_vtable_indices() array") \ |
7956 | 80 f(local_interfaces_bytes, IK_local_interfaces, \ |
81 "Number of bytes used by the InstanceKlass::local_interfaces() array") \ | |
82 f(transitive_interfaces_bytes, IK_transitive_interfaces, \ | |
83 "Number of bytes used by the InstanceKlass::transitive_interfaces() array") \ | |
84 f(fields_bytes, IK_fields, \ | |
85 "Number of bytes used by the InstanceKlass::fields() array") \ | |
86 f(inner_classes_bytes, IK_inner_classes, \ | |
87 "Number of bytes used by the InstanceKlass::inner_classes() array") \ | |
88 f(signers_bytes, IK_signers, \ | |
89 "Number of bytes used by the InstanceKlass::singers() array") \ | |
90 f(class_annotations_bytes, class_annotations, \ | |
91 "Size of class annotations") \ | |
8031 | 92 f(class_type_annotations_bytes, class_type_annotations, \ |
93 "Size of class type annotations") \ | |
7956 | 94 f(fields_annotations_bytes, fields_annotations, \ |
95 "Size of field annotations") \ | |
8031 | 96 f(fields_type_annotations_bytes, fields_type_annotations, \ |
97 "Size of field type annotations") \ | |
7956 | 98 f(methods_annotations_bytes, methods_annotations, \ |
99 "Size of method annotations") \ | |
100 f(methods_parameter_annotations_bytes, methods_parameter_annotations, \ | |
101 "Size of method parameter annotations") \ | |
8031 | 102 f(methods_type_annotations_bytes, methods_type_annotations, \ |
103 "Size of methods type annotations") \ | |
7956 | 104 f(methods_default_annotations_bytes, methods_default_annotations, \ |
105 "Size of methods default annotations") \ | |
106 f(annotations_bytes, annotations, \ | |
107 "Size of all annotations") \ | |
108 f(cp_bytes, Cp, \ | |
109 "Size of InstanceKlass::constants()") \ | |
110 f(cp_tags_bytes, CpTags, \ | |
111 "Size of InstanceKlass::constants()->tags()") \ | |
112 f(cp_cache_bytes, CpCache, \ | |
113 "Size of InstanceKlass::constants()->cache()") \ | |
114 f(cp_operands_bytes, CpOperands, \ | |
115 "Size of InstanceKlass::constants()->operands()") \ | |
116 f(cp_refmap_bytes, CpRefMap, \ | |
117 "Size of InstanceKlass::constants()->reference_map()") \ | |
118 f(cp_all_bytes, CpAll, \ | |
119 "Sum of Cp + CpTags + CpCache + CpOperands + CpRefMap") \ | |
120 f(method_count, MethodCount, \ | |
121 "Number of methods in this class") \ | |
122 f(method_bytes, MethodBytes, \ | |
123 "Size of the Method object") \ | |
124 f(const_method_bytes, ConstMethod, \ | |
125 "Size of the ConstMethod object") \ | |
126 f(method_data_bytes, MethodData, \ | |
127 "Size of the MethodData object") \ | |
128 f(stackmap_bytes, StackMap, \ | |
129 "Size of the stackmap_data") \ | |
130 f(bytecode_bytes, Bytecodes, \ | |
131 "Of the MethodBytes column, how much are the space taken up by bytecodes") \ | |
132 f(method_all_bytes, MethodAll, \ | |
133 "Sum of MethodBytes + Constmethod + Stackmap + Methoddata") \ | |
134 f(ro_bytes, ROAll, \ | |
135 "Size of all class meta data that could (potentially) be placed " \ | |
136 "in read-only memory. (This could change with CDS design)") \ | |
137 f(rw_bytes, RWAll, \ | |
138 "Size of all class meta data that must be placed in read/write " \ | |
139 "memory. (This could change with CDS design) ") \ | |
140 f(total_bytes, Total, \ | |
141 "ROAll + RWAll. Note that this does NOT include InstBytes.") | |
142 | |
143 // Size statistics for a Klass - filled in by Klass::collect_statistics() | |
144 class KlassSizeStats { | |
145 public: | |
146 #define COUNT_KLASS_SIZE_STATS_FIELD(field, name, help) _index_ ## field, | |
147 #define DECLARE_KLASS_SIZE_STATS_FIELD(field, name, help) julong _ ## field; | |
148 | |
149 enum { | |
150 HEAP_INSPECTION_COLUMNS_DO(COUNT_KLASS_SIZE_STATS_FIELD) | |
151 _num_columns | |
152 }; | |
153 | |
154 HEAP_INSPECTION_COLUMNS_DO(DECLARE_KLASS_SIZE_STATS_FIELD) | |
155 | |
156 static int count(oop x) { | |
12316
190899198332
7195622: CheckUnhandledOops has limited usefulness now
hseigel
parents:
11113
diff
changeset
|
157 return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0)); |
7956 | 158 } |
159 | |
160 static int count_array(objArrayOop x) { | |
12316
190899198332
7195622: CheckUnhandledOops has limited usefulness now
hseigel
parents:
11113
diff
changeset
|
161 return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0)); |
7956 | 162 } |
163 | |
164 template <class T> static int count(T* x) { | |
165 return (HeapWordSize * ((x) ? (x)->size() : 0)); | |
166 } | |
167 | |
168 template <class T> static int count_array(T* x) { | |
169 if (x == NULL) { | |
170 return 0; | |
171 } | |
172 if (x->length() == 0) { | |
173 // This is a shared array, e.g., Universe::the_empty_int_array(). Don't | |
174 // count it to avoid double-counting. | |
175 return 0; | |
176 } | |
177 return HeapWordSize * x->size(); | |
178 } | |
179 }; | |
180 | |
181 | |
182 | |
183 | |
6197 | 184 class KlassInfoEntry: public CHeapObj<mtInternal> { |
0 | 185 private: |
186 KlassInfoEntry* _next; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
187 Klass* _klass; |
0 | 188 long _instance_count; |
189 size_t _instance_words; | |
7956 | 190 long _index; |
0 | 191 |
192 public: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
193 KlassInfoEntry(Klass* k, KlassInfoEntry* next) : |
7956 | 194 _klass(k), _instance_count(0), _instance_words(0), _next(next), _index(-1) |
0 | 195 {} |
10265
92ef81e2f571
8003557: NPG: Klass* const k should be const Klass* k.
minqi
parents:
8031
diff
changeset
|
196 KlassInfoEntry* next() const { return _next; } |
92ef81e2f571
8003557: NPG: Klass* const k should be const Klass* k.
minqi
parents:
8031
diff
changeset
|
197 bool is_equal(const Klass* k) { return k == _klass; } |
92ef81e2f571
8003557: NPG: Klass* const k should be const Klass* k.
minqi
parents:
8031
diff
changeset
|
198 Klass* klass() const { return _klass; } |
92ef81e2f571
8003557: NPG: Klass* const k should be const Klass* k.
minqi
parents:
8031
diff
changeset
|
199 long count() const { return _instance_count; } |
0 | 200 void set_count(long ct) { _instance_count = ct; } |
10265
92ef81e2f571
8003557: NPG: Klass* const k should be const Klass* k.
minqi
parents:
8031
diff
changeset
|
201 size_t words() const { return _instance_words; } |
0 | 202 void set_words(size_t wds) { _instance_words = wds; } |
7956 | 203 void set_index(long index) { _index = index; } |
10265
92ef81e2f571
8003557: NPG: Klass* const k should be const Klass* k.
minqi
parents:
8031
diff
changeset
|
204 long index() const { return _index; } |
0 | 205 int compare(KlassInfoEntry* e1, KlassInfoEntry* e2); |
206 void print_on(outputStream* st) const; | |
7956 | 207 const char* name() const; |
0 | 208 }; |
209 | |
11113
2cbc8f3011a0
8015972: Refactor the sending of the object count after GC event
ehelin
parents:
10405
diff
changeset
|
210 class KlassInfoClosure : public StackObj { |
2cbc8f3011a0
8015972: Refactor the sending of the object count after GC event
ehelin
parents:
10405
diff
changeset
|
211 public: |
2cbc8f3011a0
8015972: Refactor the sending of the object count after GC event
ehelin
parents:
10405
diff
changeset
|
212 // Called for each KlassInfoEntry. |
2cbc8f3011a0
8015972: Refactor the sending of the object count after GC event
ehelin
parents:
10405
diff
changeset
|
213 virtual void do_cinfo(KlassInfoEntry* cie) = 0; |
2cbc8f3011a0
8015972: Refactor the sending of the object count after GC event
ehelin
parents:
10405
diff
changeset
|
214 }; |
2cbc8f3011a0
8015972: Refactor the sending of the object count after GC event
ehelin
parents:
10405
diff
changeset
|
215 |
6197 | 216 class KlassInfoBucket: public CHeapObj<mtInternal> { |
0 | 217 private: |
218 KlassInfoEntry* _list; | |
219 KlassInfoEntry* list() { return _list; } | |
220 void set_list(KlassInfoEntry* l) { _list = l; } | |
221 public: | |
10265
92ef81e2f571
8003557: NPG: Klass* const k should be const Klass* k.
minqi
parents:
8031
diff
changeset
|
222 KlassInfoEntry* lookup(Klass* k); |
0 | 223 void initialize() { _list = NULL; } |
224 void empty(); | |
225 void iterate(KlassInfoClosure* cic); | |
226 }; | |
227 | |
228 class KlassInfoTable: public StackObj { | |
229 private: | |
230 int _size; | |
10405 | 231 static const int _num_buckets = 20011; |
232 size_t _size_of_instances_in_words; | |
0 | 233 |
234 // An aligned reference address (typically the least | |
235 // address in the perm gen) used for hashing klass | |
236 // objects. | |
237 HeapWord* _ref; | |
238 | |
239 KlassInfoBucket* _buckets; | |
10265
92ef81e2f571
8003557: NPG: Klass* const k should be const Klass* k.
minqi
parents:
8031
diff
changeset
|
240 uint hash(const Klass* p); |
92ef81e2f571
8003557: NPG: Klass* const k should be const Klass* k.
minqi
parents:
8031
diff
changeset
|
241 KlassInfoEntry* lookup(Klass* k); // allocates if not found! |
7956 | 242 |
243 class AllClassesFinder : public KlassClosure { | |
244 KlassInfoTable *_table; | |
245 public: | |
246 AllClassesFinder(KlassInfoTable* table) : _table(table) {} | |
247 virtual void do_klass(Klass* k); | |
248 }; | |
0 | 249 |
250 public: | |
10405 | 251 KlassInfoTable(bool need_class_stats); |
0 | 252 ~KlassInfoTable(); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
253 bool record_instance(const oop obj); |
0 | 254 void iterate(KlassInfoClosure* cic); |
11
3c1dbcaaab1d
6621728: Heap inspection should not crash in the face of C-heap exhaustion
ysr
parents:
0
diff
changeset
|
255 bool allocation_failed() { return _buckets == NULL; } |
10405 | 256 size_t size_of_instances_in_words() const; |
7956 | 257 |
258 friend class KlassInfoHisto; | |
0 | 259 }; |
260 | |
261 class KlassInfoHisto : public StackObj { | |
262 private: | |
10405 | 263 static const int _histo_initial_size = 1000; |
7956 | 264 KlassInfoTable *_cit; |
0 | 265 GrowableArray<KlassInfoEntry*>* _elements; |
266 GrowableArray<KlassInfoEntry*>* elements() const { return _elements; } | |
267 const char* _title; | |
268 const char* title() const { return _title; } | |
269 static int sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2); | |
270 void print_elements(outputStream* st) const; | |
7956 | 271 void print_class_stats(outputStream* st, bool csv_format, const char *columns); |
272 julong annotations_bytes(Array<AnnotationArray*>* p) const; | |
273 const char *_selected_columns; | |
274 bool is_selected(const char *col_name); | |
275 void print_title(outputStream* st, bool csv_format, | |
276 bool selected_columns_table[], int width_table[], | |
277 const char *name_table[]); | |
278 | |
279 template <class T> static int count_bytes(T* x) { | |
280 return (HeapWordSize * ((x) ? (x)->size() : 0)); | |
281 } | |
282 | |
283 template <class T> static int count_bytes_array(T* x) { | |
284 if (x == NULL) { | |
285 return 0; | |
286 } | |
287 if (x->length() == 0) { | |
288 // This is a shared array, e.g., Universe::the_empty_int_array(). Don't | |
289 // count it to avoid double-counting. | |
290 return 0; | |
291 } | |
292 return HeapWordSize * x->size(); | |
293 } | |
294 | |
295 // returns a format string to print a julong with the given width. E.g, | |
296 // printf(num_fmt(6), julong(10)) would print out the number 10 with 4 | |
297 // leading spaces. | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12823
diff
changeset
|
298 PRAGMA_DIAG_PUSH |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12823
diff
changeset
|
299 PRAGMA_FORMAT_NONLITERAL_IGNORED |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12823
diff
changeset
|
300 |
7956 | 301 static void print_julong(outputStream* st, int width, julong n) { |
302 int num_spaces = width - julong_width(n); | |
303 if (num_spaces > 0) { | |
304 st->print(str_fmt(num_spaces), ""); | |
305 } | |
306 st->print(JULONG_FORMAT, n); | |
307 } | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12823
diff
changeset
|
308 PRAGMA_DIAG_POP |
7956 | 309 |
310 static char* perc_fmt(int width) { | |
311 static char buf[32]; | |
312 jio_snprintf(buf, sizeof(buf), "%%%d.1f%%%%", width-1); | |
313 return buf; | |
314 } | |
315 | |
316 static char* str_fmt(int width) { | |
317 static char buf[32]; | |
318 jio_snprintf(buf, sizeof(buf), "%%%ds", width); | |
319 return buf; | |
320 } | |
321 | |
322 static int julong_width(julong n) { | |
323 if (n == 0) { | |
324 return 1; | |
325 } | |
326 int w = 0; | |
327 while (n > 0) { | |
328 n /= 10; | |
329 w += 1; | |
330 } | |
331 return w; | |
332 } | |
333 | |
334 static int col_width(julong n, const char *name) { | |
335 int w = julong_width(n); | |
336 int min = (int)(strlen(name)); | |
337 if (w < min) { | |
338 w = min; | |
339 } | |
340 // add a leading space for separation. | |
341 return w + 1; | |
342 } | |
343 | |
0 | 344 public: |
10405 | 345 KlassInfoHisto(KlassInfoTable* cit, const char* title); |
0 | 346 ~KlassInfoHisto(); |
347 void add(KlassInfoEntry* cie); | |
7956 | 348 void print_histo_on(outputStream* st, bool print_class_stats, bool csv_format, const char *columns); |
0 | 349 void sort(); |
350 }; | |
351 | |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
352 #endif // INCLUDE_SERVICES |
0 | 353 |
10405 | 354 // These declarations are needed since teh declaration of KlassInfoTable and |
355 // KlassInfoClosure are guarded by #if INLCUDE_SERVICES | |
356 class KlassInfoTable; | |
357 class KlassInfoClosure; | |
358 | |
7956 | 359 class HeapInspection : public StackObj { |
360 bool _csv_format; // "comma separated values" format for spreadsheet. | |
361 bool _print_help; | |
362 bool _print_class_stats; | |
363 const char* _columns; | |
0 | 364 public: |
7956 | 365 HeapInspection(bool csv_format, bool print_help, |
366 bool print_class_stats, const char *columns) : | |
367 _csv_format(csv_format), _print_help(print_help), | |
368 _print_class_stats(print_class_stats), _columns(columns) {} | |
10405 | 369 void heap_inspection(outputStream* st) NOT_SERVICES_RETURN; |
370 size_t populate_table(KlassInfoTable* cit, BoolObjectClosure* filter = NULL) NOT_SERVICES_RETURN; | |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
371 static void find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) NOT_SERVICES_RETURN; |
10405 | 372 private: |
373 void iterate_over_heap(KlassInfoTable* cit, BoolObjectClosure* filter = NULL); | |
0 | 374 }; |
1972 | 375 |
376 #endif // SHARE_VM_MEMORY_HEAPINSPECTION_HPP |