comparison src/share/vm/services/memBaseline.hpp @ 6197:d2a62e0f25eb

6995781: Native Memory Tracking (Phase 1) 7151532: DCmd for hotspot native memory tracking Summary: Implementation of native memory tracking phase 1, which tracks VM native memory usage, and related DCmd Reviewed-by: acorn, coleenp, fparain
author zgu
date Thu, 28 Jun 2012 17:03:16 -0400
parents
children 716c64bda5ba
comparison
equal deleted inserted replaced
6174:74533f63b116 6197:d2a62e0f25eb
1 /*
2 * Copyright (c) 2012, 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 #ifndef SHARE_VM_SERVICES_MEM_BASELINE_HPP
26 #define SHARE_VM_SERVICES_MEM_BASELINE_HPP
27
28 #include "memory/allocation.hpp"
29 #include "runtime/mutex.hpp"
30 #include "services/memPtr.hpp"
31 #include "services/memSnapshot.hpp"
32
33 // compare unsigned number
34 #define UNSIGNED_COMPARE(a, b) ((a > b) ? 1 : ((a == b) ? 0 : -1))
35
36 /*
37 * MallocCallsitePointer and VMCallsitePointer are used
38 * to baseline memory blocks with their callsite information.
39 * They are only available when detail tracking is turned
40 * on.
41 */
42
43 /* baselined malloc record aggregated by callsite */
44 class MallocCallsitePointer : public MemPointer {
45 private:
46 size_t _count; // number of malloc invocation from this callsite
47 size_t _amount; // total amount of memory malloc-ed from this callsite
48
49 public:
50 MallocCallsitePointer() {
51 _count = 0;
52 _amount = 0;
53 }
54
55 MallocCallsitePointer(address pc) : MemPointer(pc) {
56 _count = 0;
57 _amount = 0;
58 }
59
60 MallocCallsitePointer& operator=(const MallocCallsitePointer& p) {
61 MemPointer::operator=(p);
62 _count = p.count();
63 _amount = p.amount();
64 return *this;
65 }
66
67 inline void inc(size_t size) {
68 _count ++;
69 _amount += size;
70 };
71
72 inline size_t count() const {
73 return _count;
74 }
75
76 inline size_t amount() const {
77 return _amount;
78 }
79 };
80
81 // baselined virtual memory record aggregated by callsite
82 class VMCallsitePointer : public MemPointer {
83 private:
84 size_t _count; // number of invocation from this callsite
85 size_t _reserved_amount; // total reserved amount
86 size_t _committed_amount; // total committed amount
87
88 public:
89 VMCallsitePointer() {
90 _count = 0;
91 _reserved_amount = 0;
92 _committed_amount = 0;
93 }
94
95 VMCallsitePointer(address pc) : MemPointer(pc) {
96 _count = 0;
97 _reserved_amount = 0;
98 _committed_amount = 0;
99 }
100
101 VMCallsitePointer& operator=(const VMCallsitePointer& p) {
102 MemPointer::operator=(p);
103 _count = p.count();
104 _reserved_amount = p.reserved_amount();
105 _committed_amount = p.committed_amount();
106 return *this;
107 }
108
109 inline void inc(size_t reserved, size_t committed) {
110 _count ++;
111 _reserved_amount += reserved;
112 _committed_amount += committed;
113 }
114
115 inline size_t count() const {
116 return _count;
117 }
118
119 inline size_t reserved_amount() const {
120 return _reserved_amount;
121 }
122
123 inline size_t committed_amount() const {
124 return _committed_amount;
125 }
126 };
127
128 // maps a memory type flag to readable name
129 typedef struct _memType2Name {
130 MEMFLAGS _flag;
131 const char* _name;
132 } MemType2Name;
133
134
135 // This class aggregates malloc'd records by memory type
136 class MallocMem : public _ValueObj {
137 private:
138 MEMFLAGS _type;
139
140 size_t _count;
141 size_t _amount;
142
143 public:
144 MallocMem() {
145 _type = mtNone;
146 _count = 0;
147 _amount = 0;
148 }
149
150 MallocMem(MEMFLAGS flags) {
151 assert(HAS_VALID_MEMORY_TYPE(flags), "no type");
152 _type = FLAGS_TO_MEMORY_TYPE(flags);
153 _count = 0;
154 _amount = 0;
155 }
156
157 inline void set_type(MEMFLAGS flag) {
158 _type = flag;
159 }
160
161 inline void clear() {
162 _count = 0;
163 _amount = 0;
164 _type = mtNone;
165 }
166
167 MallocMem& operator=(const MallocMem& m) {
168 assert(_type == m.type(), "different type");
169 _count = m.count();
170 _amount = m.amount();
171 return *this;
172 }
173
174 inline void inc(size_t amt) {
175 _amount += amt;
176 _count ++;
177 }
178
179 inline void reduce(size_t amt) {
180 assert(_amount >= amt, "Just check");
181 _amount -= amt;
182 }
183
184 inline void overwrite_counter(size_t count) {
185 _count = count;
186 }
187
188 inline MEMFLAGS type() const {
189 return _type;
190 }
191
192 inline bool is_type(MEMFLAGS flags) const {
193 return FLAGS_TO_MEMORY_TYPE(flags) == _type;
194 }
195
196 inline size_t count() const {
197 return _count;
198 }
199
200 inline size_t amount() const {
201 return _amount;
202 }
203 };
204
205 // This class records live arena's memory usage
206 class ArenaMem : public MallocMem {
207 public:
208 ArenaMem(MEMFLAGS typeflag): MallocMem(typeflag) {
209 }
210 ArenaMem() { }
211 };
212
213 // This class aggregates virtual memory by its memory type
214 class VMMem : public _ValueObj {
215 private:
216 MEMFLAGS _type;
217
218 size_t _count;
219 size_t _reserved_amount;
220 size_t _committed_amount;
221
222 public:
223 VMMem() {
224 _type = mtNone;
225 _count = 0;
226 _reserved_amount = 0;
227 _committed_amount = 0;
228 }
229
230 VMMem(MEMFLAGS flags) {
231 assert(HAS_VALID_MEMORY_TYPE(flags), "no type");
232 _type = FLAGS_TO_MEMORY_TYPE(flags);
233 _count = 0;
234 _reserved_amount = 0;
235 _committed_amount = 0;
236 }
237
238 inline void clear() {
239 _type = mtNone;
240 _count = 0;
241 _reserved_amount = 0;
242 _committed_amount = 0;
243 }
244
245 inline void set_type(MEMFLAGS flags) {
246 _type = FLAGS_TO_MEMORY_TYPE(flags);
247 }
248
249 VMMem& operator=(const VMMem& m) {
250 assert(_type == m.type(), "different type");
251
252 _count = m.count();
253 _reserved_amount = m.reserved_amount();
254 _committed_amount = m.committed_amount();
255 return *this;
256 }
257
258
259 inline MEMFLAGS type() const {
260 return _type;
261 }
262
263 inline bool is_type(MEMFLAGS flags) const {
264 return FLAGS_TO_MEMORY_TYPE(flags) == _type;
265 }
266
267 inline void inc(size_t reserved_amt, size_t committed_amt) {
268 _reserved_amount += reserved_amt;
269 _committed_amount += committed_amt;
270 _count ++;
271 }
272
273 inline size_t count() const {
274 return _count;
275 }
276
277 inline size_t reserved_amount() const {
278 return _reserved_amount;
279 }
280
281 inline size_t committed_amount() const {
282 return _committed_amount;
283 }
284 };
285
286
287
288 #define NUMBER_OF_MEMORY_TYPE (mt_number_of_types + 1)
289
290 class BaselineReporter;
291 class BaselineComparisonReporter;
292
293 /*
294 * This class baselines current memory snapshot.
295 * A memory baseline summarizes memory usage by memory type,
296 * aggregates memory usage by callsites when detail tracking
297 * is on.
298 */
299 class MemBaseline : public _ValueObj {
300 friend class BaselineReporter;
301 friend class BaselineComparisonReporter;
302
303 private:
304 // overall summaries
305 size_t _total_malloced;
306 size_t _total_vm_reserved;
307 size_t _total_vm_committed;
308 size_t _number_of_classes;
309 size_t _number_of_threads;
310
311 // if it has properly baselined
312 bool _baselined;
313
314 // we categorize memory into three categories within the memory type
315 MallocMem _malloc_data[NUMBER_OF_MEMORY_TYPE];
316 VMMem _vm_data[NUMBER_OF_MEMORY_TYPE];
317 ArenaMem _arena_data[NUMBER_OF_MEMORY_TYPE];
318
319 // memory records that aggregate memory usage by callsites.
320 // only available when detail tracking is on.
321 MemPointerArray* _malloc_cs;
322 MemPointerArray* _vm_cs;
323
324 private:
325 static MemType2Name MemType2NameMap[NUMBER_OF_MEMORY_TYPE];
326
327 private:
328 // should not use copy constructor
329 MemBaseline(MemBaseline& copy) { ShouldNotReachHere(); }
330
331 public:
332 // create a memory baseline
333 MemBaseline();
334
335 virtual ~MemBaseline();
336
337 inline bool baselined() const {
338 return _baselined;
339 }
340
341 MemBaseline& operator=(const MemBaseline& other);
342
343 // reset the baseline for reuse
344 void clear();
345
346 // baseline the snapshot
347 bool baseline(MemSnapshot& snapshot, bool summary_only = true);
348
349 bool baseline(const MemPointerArray* malloc_records,
350 const MemPointerArray* vm_records,
351 bool summary_only = true);
352
353 // total malloc'd memory of specified memory type
354 inline size_t malloc_amount(MEMFLAGS flag) const {
355 return _malloc_data[flag2index(flag)].amount();
356 }
357 // number of malloc'd memory blocks of specified memory type
358 inline size_t malloc_count(MEMFLAGS flag) const {
359 return _malloc_data[flag2index(flag)].count();
360 }
361 // total memory used by arenas of specified memory type
362 inline size_t arena_amount(MEMFLAGS flag) const {
363 return _arena_data[flag2index(flag)].amount();
364 }
365 // number of arenas of specified memory type
366 inline size_t arena_count(MEMFLAGS flag) const {
367 return _arena_data[flag2index(flag)].count();
368 }
369 // total reserved memory of specified memory type
370 inline size_t reserved_amount(MEMFLAGS flag) const {
371 return _vm_data[flag2index(flag)].reserved_amount();
372 }
373 // total committed memory of specified memory type
374 inline size_t committed_amount(MEMFLAGS flag) const {
375 return _vm_data[flag2index(flag)].committed_amount();
376 }
377 // total memory (malloc'd + mmap'd + arena) of specified
378 // memory type
379 inline size_t total_amount(MEMFLAGS flag) const {
380 int index = flag2index(flag);
381 return _malloc_data[index].amount() +
382 _vm_data[index].reserved_amount() +
383 _arena_data[index].amount();
384 }
385
386 /* overall summaries */
387
388 // total malloc'd memory in snapshot
389 inline size_t total_malloc_amount() const {
390 return _total_malloced;
391 }
392 // total mmap'd memory in snapshot
393 inline size_t total_reserved_amount() const {
394 return _total_vm_reserved;
395 }
396 // total committed memory in snapshot
397 inline size_t total_committed_amount() const {
398 return _total_vm_committed;
399 }
400 // number of loaded classes
401 inline size_t number_of_classes() const {
402 return _number_of_classes;
403 }
404 // number of running threads
405 inline size_t number_of_threads() const {
406 return _number_of_threads;
407 }
408 // lookup human readable name of a memory type
409 static const char* type2name(MEMFLAGS type);
410
411 private:
412 // convert memory flag to the index to mapping table
413 int flag2index(MEMFLAGS flag) const;
414
415 // reset baseline values
416 void reset();
417
418 // summarize the records in global snapshot
419 bool baseline_malloc_summary(const MemPointerArray* malloc_records);
420 bool baseline_vm_summary(const MemPointerArray* vm_records);
421 bool baseline_malloc_details(const MemPointerArray* malloc_records);
422 bool baseline_vm_details(const MemPointerArray* vm_records);
423
424 // print a line of malloc'd memory aggregated by callsite
425 void print_malloc_callsite(outputStream* st, address pc, size_t size,
426 size_t count, int diff_amt, int diff_count) const;
427 // print a line of mmap'd memory aggregated by callsite
428 void print_vm_callsite(outputStream* st, address pc, size_t rsz,
429 size_t csz, int diff_rsz, int diff_csz) const;
430
431 // sorting functions for raw records
432 static int malloc_sort_by_pc(const void* p1, const void* p2);
433 static int malloc_sort_by_addr(const void* p1, const void* p2);
434
435 static int vm_sort_by_pc(const void* p1, const void* p2);
436 static int vm_sort_by_addr(const void* p1, const void* p2);
437
438 private:
439 // sorting functions for baselined records
440 static int bl_malloc_sort_by_size(const void* p1, const void* p2);
441 static int bl_vm_sort_by_size(const void* p1, const void* p2);
442 static int bl_malloc_sort_by_pc(const void* p1, const void* p2);
443 static int bl_vm_sort_by_pc(const void* p1, const void* p2);
444 };
445
446
447 #endif // SHARE_VM_SERVICES_MEM_BASELINE_HPP