src/share/vm/services/memReporter.hpp

changeset 7074
833b0f92429a
parent 6198
55fb97c4c58d
child 7267
417e3b8d04c5
equal deleted inserted replaced
7073:4d3a43351904 7074:833b0f92429a
1 /* 1 /*
2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2012, 2014, 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 #ifndef SHARE_VM_SERVICES_MEM_REPORTER_HPP 25 #ifndef SHARE_VM_SERVICES_MEM_REPORTER_HPP
26 #define SHARE_VM_SERVICES_MEM_REPORTER_HPP 26 #define SHARE_VM_SERVICES_MEM_REPORTER_HPP
27 27
28 #include "runtime/mutexLocker.hpp" 28 #if INCLUDE_NMT
29
30 #include "oops/instanceKlass.hpp"
29 #include "services/memBaseline.hpp" 31 #include "services/memBaseline.hpp"
30 #include "services/memTracker.hpp" 32 #include "services/nmtCommon.hpp"
31 #include "utilities/ostream.hpp" 33 #include "services/mallocTracker.hpp"
32 #include "utilities/macros.hpp" 34 #include "services/virtualMemoryTracker.hpp"
33 35
34 #if INCLUDE_NMT 36 /*
35 37 * Base class that provides helpers
36 /* 38 */
37 * MemBaselineReporter reports data to this outputer class, 39 class MemReporterBase : public StackObj {
38 * ReportOutputer is responsible for format, store and redirect 40 private:
39 * the data to the final destination. 41 size_t _scale; // report in this scale
40 */ 42 outputStream* _output; // destination
41 class BaselineOutputer : public StackObj { 43
42 public: 44 public:
43 // start to report memory usage in specified scale. 45 MemReporterBase(outputStream* out = NULL, size_t scale = K)
44 // if report_diff = true, the reporter reports baseline comparison 46 : _scale(scale) {
45 // information. 47 _output = (out == NULL) ? tty : out;
46 48 }
47 virtual void start(size_t scale, bool report_diff = false) = 0; 49
48 // Done reporting 50 protected:
49 virtual void done() = 0; 51 inline outputStream* output() const {
50 52 return _output;
51 /* report baseline summary information */ 53 }
52 virtual void total_usage(size_t total_reserved, 54 // Current reporting scale
53 size_t total_committed) = 0; 55 inline const char* current_scale() const {
54 virtual void num_of_classes(size_t classes) = 0; 56 return NMTUtil::scale_name(_scale);
55 virtual void num_of_threads(size_t threads) = 0; 57 }
56 58 // Convert memory amount in bytes to current reporting scale
57 virtual void thread_info(size_t stack_reserved_amt, size_t stack_committed_amt) = 0; 59 inline size_t amount_in_current_scale(size_t amount) const {
58 60 return NMTUtil::amount_in_scale(amount, _scale);
59 /* report baseline summary comparison */ 61 }
60 virtual void diff_total_usage(size_t total_reserved, 62
61 size_t total_committed, 63 // Convert diff amount in bytes to current reporting scale
62 int reserved_diff, 64 inline long diff_in_current_scale(size_t s1, size_t s2) const {
63 int committed_diff) = 0; 65 long amount = (long)(s1 - s2);
64 virtual void diff_num_of_classes(size_t classes, int diff) = 0; 66 long scale = (long)_scale;
65 virtual void diff_num_of_threads(size_t threads, int diff) = 0; 67 amount = (amount > 0) ? (amount + scale / 2) : (amount - scale / 2);
66 68 return amount / scale;
67 virtual void diff_thread_info(size_t stack_reserved, size_t stack_committed, 69 }
68 int stack_reserved_diff, int stack_committed_diff) = 0; 70
69 71 // Helper functions
70 72 // Calculate total reserved and committed amount
71 /* 73 size_t reserved_total(const MallocMemory* malloc, const VirtualMemory* vm) const;
72 * memory summary by memory types. 74 size_t committed_total(const MallocMemory* malloc, const VirtualMemory* vm) const;
73 * for each memory type, following summaries are reported: 75
74 * - reserved amount, committed amount 76
75 * - malloc'd amount, malloc count 77 // Print summary total, malloc and virtual memory
76 * - arena amount, arena count 78 void print_total(size_t reserved, size_t committed) const;
77 */ 79 void print_malloc(size_t amount, size_t count) const;
78 80 void print_virtual_memory(size_t reserved, size_t committed) const;
79 // start reporting memory summary by memory type 81
80 virtual void start_category_summary() = 0; 82 void print_malloc_line(size_t amount, size_t count) const;
81 83 void print_virtual_memory_line(size_t reserved, size_t committed) const;
82 virtual void category_summary(MEMFLAGS type, size_t reserved_amt, 84 void print_arena_line(size_t amount, size_t count) const;
83 size_t committed_amt, 85
84 size_t malloc_amt, size_t malloc_count, 86 void print_virtual_memory_region(const char* type, address base, size_t size) const;
85 size_t arena_amt, size_t arena_count) = 0; 87 };
86 88
87 virtual void diff_category_summary(MEMFLAGS type, size_t cur_reserved_amt, 89 /*
88 size_t cur_committed_amt, 90 * The class is for generating summary tracking report.
89 size_t cur_malloc_amt, size_t cur_malloc_count, 91 */
90 size_t cur_arena_amt, size_t cur_arena_count, 92 class MemSummaryReporter : public MemReporterBase {
91 int reserved_diff, int committed_diff, int malloc_diff, 93 private:
92 int malloc_count_diff, int arena_diff, 94 MallocMemorySnapshot* _malloc_snapshot;
93 int arena_count_diff) = 0; 95 VirtualMemorySnapshot* _vm_snapshot;
94 96 size_t _class_count;
95 virtual void done_category_summary() = 0; 97
96 98 public:
97 virtual void start_virtual_memory_map() = 0; 99 // Report summary tracking data from global snapshots directly.
98 virtual void reserved_memory_region(MEMFLAGS type, address base, address end, size_t size, address pc) = 0; 100 // This constructor is used for final reporting and hs_err reporting.
99 virtual void committed_memory_region(address base, address end, size_t size, address pc) = 0; 101 MemSummaryReporter(MallocMemorySnapshot* malloc_snapshot,
100 virtual void done_virtual_memory_map() = 0; 102 VirtualMemorySnapshot* vm_snapshot, outputStream* output,
101 103 size_t class_count = 0, size_t scale = K) :
102 /* 104 MemReporterBase(output, scale),
103 * Report callsite information 105 _malloc_snapshot(malloc_snapshot),
104 */ 106 _vm_snapshot(vm_snapshot) {
105 virtual void start_callsite() = 0; 107 if (class_count == 0) {
106 virtual void malloc_callsite(address pc, size_t malloc_amt, size_t malloc_count) = 0; 108 _class_count = InstanceKlass::number_of_instance_classes();
107 virtual void virtual_memory_callsite(address pc, size_t reserved_amt, size_t committed_amt) = 0; 109 } else {
108 110 _class_count = class_count;
109 virtual void diff_malloc_callsite(address pc, size_t cur_malloc_amt, size_t cur_malloc_count, 111 }
110 int malloc_diff, int malloc_count_diff) = 0; 112 }
111 virtual void diff_virtual_memory_callsite(address pc, size_t cur_reserved_amt, size_t cur_committed_amt, 113 // This constructor is for normal reporting from a recent baseline.
112 int reserved_diff, int committed_diff) = 0; 114 MemSummaryReporter(MemBaseline& baseline, outputStream* output,
113 115 size_t scale = K) : MemReporterBase(output, scale),
114 virtual void done_callsite() = 0; 116 _malloc_snapshot(baseline.malloc_memory_snapshot()),
115 117 _vm_snapshot(baseline.virtual_memory_snapshot()),
116 // return current scale in "KB", "MB" or "GB" 118 _class_count(baseline.class_count()) { }
117 static const char* memory_unit(size_t scale); 119
118 }; 120
119 121 // Generate summary report
120 /* 122 virtual void report();
121 * This class reports processed data from a baseline or 123 private:
122 * the changes between the two baseline. 124 // Report summary for each memory type
123 */ 125 void report_summary_of_type(MEMFLAGS type, MallocMemory* malloc_memory,
124 class BaselineReporter : public StackObj { 126 VirtualMemory* virtual_memory);
125 private: 127 };
126 BaselineOutputer& _outputer; 128
127 size_t _scale; 129 /*
128 130 * The class is for generating detail tracking report.
129 public: 131 */
130 // construct a reporter that reports memory usage 132 class MemDetailReporter : public MemSummaryReporter {
131 // in specified scale 133 private:
132 BaselineReporter(BaselineOutputer& outputer, size_t scale = K): 134 MemBaseline& _baseline;
133 _outputer(outputer) { 135
134 _scale = scale; 136 public:
135 } 137 MemDetailReporter(MemBaseline& baseline, outputStream* output, size_t scale = K) :
136 virtual void report_baseline(const MemBaseline& baseline, bool summary_only = false); 138 MemSummaryReporter(baseline, output, scale),
137 virtual void diff_baselines(const MemBaseline& cur, const MemBaseline& prev, 139 _baseline(baseline) { }
138 bool summary_only = false); 140
139 141 // Generate detail report.
140 void set_scale(size_t scale); 142 // The report contains summary and detail sections.
141 size_t scale() const { return _scale; } 143 virtual void report() {
142 144 MemSummaryReporter::report();
143 private: 145 report_virtual_memory_map();
144 void report_summaries(const MemBaseline& baseline); 146 report_detail();
145 void report_virtual_memory_map(const MemBaseline& baseline); 147 }
146 void report_callsites(const MemBaseline& baseline); 148
147 149 private:
148 void diff_summaries(const MemBaseline& cur, const MemBaseline& prev); 150 // Report detail tracking data.
149 void diff_callsites(const MemBaseline& cur, const MemBaseline& prev); 151 void report_detail();
150 152 // Report virtual memory map
151 // calculate memory size in current memory scale 153 void report_virtual_memory_map();
152 size_t amount_in_current_scale(size_t amt) const; 154 // Report malloc allocation sites
153 // diff two unsigned values in current memory scale 155 void report_malloc_sites();
154 int diff_in_current_scale(size_t value1, size_t value2) const; 156 // Report virtual memory reservation sites
155 // diff two unsigned value 157 void report_virtual_memory_allocation_sites();
156 int diff(size_t value1, size_t value2) const; 158
157 }; 159 // Report a virtual memory region
158 160 void report_virtual_memory_region(const ReservedMemoryRegion* rgn);
159 /* 161 };
160 * tty output implementation. Native memory tracking 162
161 * DCmd uses this outputer. 163 /*
162 */ 164 * The class is for generating summary comparison report.
163 class BaselineTTYOutputer : public BaselineOutputer { 165 * It compares current memory baseline against an early baseline.
164 private: 166 */
165 size_t _scale; 167 class MemSummaryDiffReporter : public MemReporterBase {
166 168 protected:
167 size_t _num_of_classes; 169 MemBaseline& _early_baseline;
168 size_t _num_of_threads; 170 MemBaseline& _current_baseline;
169 size_t _thread_stack_reserved; 171
170 size_t _thread_stack_committed; 172 public:
171 173 MemSummaryDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline,
172 int _num_of_classes_diff; 174 outputStream* output, size_t scale = K) : MemReporterBase(output, scale),
173 int _num_of_threads_diff; 175 _early_baseline(early_baseline), _current_baseline(current_baseline) {
174 int _thread_stack_reserved_diff; 176 assert(early_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined");
175 int _thread_stack_committed_diff; 177 assert(current_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined");
176 178 }
177 outputStream* _output; 179
178 180 // Generate summary comparison report
179 public: 181 virtual void report_diff();
180 BaselineTTYOutputer(outputStream* st) { 182
181 _scale = K; 183 private:
182 _num_of_classes = 0; 184 // report the comparison of each memory type
183 _num_of_threads = 0; 185 void diff_summary_of_type(MEMFLAGS type,
184 _thread_stack_reserved = 0; 186 const MallocMemory* early_malloc, const VirtualMemory* early_vm,
185 _thread_stack_committed = 0; 187 const MallocMemory* current_malloc, const VirtualMemory* current_vm) const;
186 _num_of_classes_diff = 0; 188
187 _num_of_threads_diff = 0; 189 protected:
188 _thread_stack_reserved_diff = 0; 190 void print_malloc_diff(size_t current_amount, size_t current_count,
189 _thread_stack_committed_diff = 0; 191 size_t early_amount, size_t early_count) const;
190 _output = st; 192 void print_virtual_memory_diff(size_t current_reserved, size_t current_committed,
191 } 193 size_t early_reserved, size_t early_committed) const;
192 194 void print_arena_diff(size_t current_amount, size_t current_count,
193 // begin reporting memory usage in specified scale 195 size_t early_amount, size_t early_count) const;
194 void start(size_t scale, bool report_diff = false); 196 };
195 // done reporting 197
196 void done(); 198 /*
197 199 * The class is for generating detail comparison report.
198 // total memory usage 200 * It compares current memory baseline against an early baseline,
199 void total_usage(size_t total_reserved, 201 * both baselines have to be detail baseline.
200 size_t total_committed); 202 */
201 // report total loaded classes 203 class MemDetailDiffReporter : public MemSummaryDiffReporter {
202 void num_of_classes(size_t classes) { 204 public:
203 _num_of_classes = classes; 205 MemDetailDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline,
204 } 206 outputStream* output, size_t scale = K) :
205 207 MemSummaryDiffReporter(early_baseline, current_baseline, output, scale) { }
206 void num_of_threads(size_t threads) { 208
207 _num_of_threads = threads; 209 // Generate detail comparison report
208 } 210 virtual void report_diff();
209 211
210 void thread_info(size_t stack_reserved_amt, size_t stack_committed_amt) { 212 // Malloc allocation site comparison
211 _thread_stack_reserved = stack_reserved_amt; 213 void diff_malloc_sites() const;
212 _thread_stack_committed = stack_committed_amt; 214 // Virutal memory reservation site comparison
213 } 215 void diff_virtual_memory_sites() const;
214 216
215 void diff_total_usage(size_t total_reserved, 217 // New malloc allocation site in recent baseline
216 size_t total_committed, 218 void new_malloc_site (const MallocSite* site) const;
217 int reserved_diff, 219 // The malloc allocation site is not in recent baseline
218 int committed_diff); 220 void old_malloc_site (const MallocSite* site) const;
219 221 // Compare malloc allocation site, it is in both baselines
220 void diff_num_of_classes(size_t classes, int diff) { 222 void diff_malloc_site(const MallocSite* early, const MallocSite* current) const;
221 _num_of_classes = classes; 223
222 _num_of_classes_diff = diff; 224 // New virtual memory allocation site in recent baseline
223 } 225 void new_virtual_memory_site (const VirtualMemoryAllocationSite* callsite) const;
224 226 // The virtual memory allocation site is not in recent baseline
225 void diff_num_of_threads(size_t threads, int diff) { 227 void old_virtual_memory_site (const VirtualMemoryAllocationSite* callsite) const;
226 _num_of_threads = threads; 228 // Compare virtual memory allocation site, it is in both baseline
227 _num_of_threads_diff = diff; 229 void diff_virtual_memory_site(const VirtualMemoryAllocationSite* early,
228 } 230 const VirtualMemoryAllocationSite* current) const;
229 231
230 void diff_thread_info(size_t stack_reserved_amt, size_t stack_committed_amt, 232 void diff_malloc_site(const NativeCallStack* stack, size_t current_size,
231 int stack_reserved_diff, int stack_committed_diff) { 233 size_t currrent_count, size_t early_size, size_t early_count) const;
232 _thread_stack_reserved = stack_reserved_amt; 234 void diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved,
233 _thread_stack_committed = stack_committed_amt; 235 size_t current_committed, size_t early_reserved, size_t early_committed) const;
234 _thread_stack_reserved_diff = stack_reserved_diff; 236 };
235 _thread_stack_committed_diff = stack_committed_diff;
236 }
237
238 /*
239 * Report memory summary categoriuzed by memory types.
240 * For each memory type, following summaries are reported:
241 * - reserved amount, committed amount
242 * - malloc-ed amount, malloc count
243 * - arena amount, arena count
244 */
245 // start reporting memory summary by memory type
246 void start_category_summary();
247 void category_summary(MEMFLAGS type, size_t reserved_amt, size_t committed_amt,
248 size_t malloc_amt, size_t malloc_count,
249 size_t arena_amt, size_t arena_count);
250
251 void diff_category_summary(MEMFLAGS type, size_t cur_reserved_amt,
252 size_t cur_committed_amt,
253 size_t cur_malloc_amt, size_t cur_malloc_count,
254 size_t cur_arena_amt, size_t cur_arena_count,
255 int reserved_diff, int committed_diff, int malloc_diff,
256 int malloc_count_diff, int arena_diff,
257 int arena_count_diff);
258
259 void done_category_summary();
260
261 // virtual memory map
262 void start_virtual_memory_map();
263 void reserved_memory_region(MEMFLAGS type, address base, address end, size_t size, address pc);
264 void committed_memory_region(address base, address end, size_t size, address pc);
265 void done_virtual_memory_map();
266
267
268 /*
269 * Report callsite information
270 */
271 void start_callsite();
272 void malloc_callsite(address pc, size_t malloc_amt, size_t malloc_count);
273 void virtual_memory_callsite(address pc, size_t reserved_amt, size_t committed_amt);
274
275 void diff_malloc_callsite(address pc, size_t cur_malloc_amt, size_t cur_malloc_count,
276 int malloc_diff, int malloc_count_diff);
277 void diff_virtual_memory_callsite(address pc, size_t cur_reserved_amt, size_t cur_committed_amt,
278 int reserved_diff, int committed_diff);
279
280 void done_callsite();
281 };
282
283 237
284 #endif // INCLUDE_NMT 238 #endif // INCLUDE_NMT
285 239
286 #endif // SHARE_VM_SERVICES_MEM_REPORTER_HPP 240 #endif
241

mercurial