1.1 --- a/src/share/vm/services/memReporter.hpp Wed Aug 27 09:36:55 2014 +0200 1.2 +++ b/src/share/vm/services/memReporter.hpp Wed Aug 27 08:19:12 2014 -0400 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -25,262 +25,217 @@ 1.11 #ifndef SHARE_VM_SERVICES_MEM_REPORTER_HPP 1.12 #define SHARE_VM_SERVICES_MEM_REPORTER_HPP 1.13 1.14 -#include "runtime/mutexLocker.hpp" 1.15 -#include "services/memBaseline.hpp" 1.16 -#include "services/memTracker.hpp" 1.17 -#include "utilities/ostream.hpp" 1.18 -#include "utilities/macros.hpp" 1.19 - 1.20 #if INCLUDE_NMT 1.21 1.22 +#include "oops/instanceKlass.hpp" 1.23 +#include "services/memBaseline.hpp" 1.24 +#include "services/nmtCommon.hpp" 1.25 +#include "services/mallocTracker.hpp" 1.26 +#include "services/virtualMemoryTracker.hpp" 1.27 + 1.28 /* 1.29 - * MemBaselineReporter reports data to this outputer class, 1.30 - * ReportOutputer is responsible for format, store and redirect 1.31 - * the data to the final destination. 1.32 - */ 1.33 -class BaselineOutputer : public StackObj { 1.34 + * Base class that provides helpers 1.35 +*/ 1.36 +class MemReporterBase : public StackObj { 1.37 + private: 1.38 + size_t _scale; // report in this scale 1.39 + outputStream* _output; // destination 1.40 + 1.41 public: 1.42 - // start to report memory usage in specified scale. 1.43 - // if report_diff = true, the reporter reports baseline comparison 1.44 - // information. 1.45 + MemReporterBase(outputStream* out = NULL, size_t scale = K) 1.46 + : _scale(scale) { 1.47 + _output = (out == NULL) ? tty : out; 1.48 + } 1.49 1.50 - virtual void start(size_t scale, bool report_diff = false) = 0; 1.51 - // Done reporting 1.52 - virtual void done() = 0; 1.53 + protected: 1.54 + inline outputStream* output() const { 1.55 + return _output; 1.56 + } 1.57 + // Current reporting scale 1.58 + inline const char* current_scale() const { 1.59 + return NMTUtil::scale_name(_scale); 1.60 + } 1.61 + // Convert memory amount in bytes to current reporting scale 1.62 + inline size_t amount_in_current_scale(size_t amount) const { 1.63 + return NMTUtil::amount_in_scale(amount, _scale); 1.64 + } 1.65 1.66 - /* report baseline summary information */ 1.67 - virtual void total_usage(size_t total_reserved, 1.68 - size_t total_committed) = 0; 1.69 - virtual void num_of_classes(size_t classes) = 0; 1.70 - virtual void num_of_threads(size_t threads) = 0; 1.71 + // Convert diff amount in bytes to current reporting scale 1.72 + inline long diff_in_current_scale(size_t s1, size_t s2) const { 1.73 + long amount = (long)(s1 - s2); 1.74 + long scale = (long)_scale; 1.75 + amount = (amount > 0) ? (amount + scale / 2) : (amount - scale / 2); 1.76 + return amount / scale; 1.77 + } 1.78 1.79 - virtual void thread_info(size_t stack_reserved_amt, size_t stack_committed_amt) = 0; 1.80 + // Helper functions 1.81 + // Calculate total reserved and committed amount 1.82 + size_t reserved_total(const MallocMemory* malloc, const VirtualMemory* vm) const; 1.83 + size_t committed_total(const MallocMemory* malloc, const VirtualMemory* vm) const; 1.84 1.85 - /* report baseline summary comparison */ 1.86 - virtual void diff_total_usage(size_t total_reserved, 1.87 - size_t total_committed, 1.88 - int reserved_diff, 1.89 - int committed_diff) = 0; 1.90 - virtual void diff_num_of_classes(size_t classes, int diff) = 0; 1.91 - virtual void diff_num_of_threads(size_t threads, int diff) = 0; 1.92 1.93 - virtual void diff_thread_info(size_t stack_reserved, size_t stack_committed, 1.94 - int stack_reserved_diff, int stack_committed_diff) = 0; 1.95 + // Print summary total, malloc and virtual memory 1.96 + void print_total(size_t reserved, size_t committed) const; 1.97 + void print_malloc(size_t amount, size_t count) const; 1.98 + void print_virtual_memory(size_t reserved, size_t committed) const; 1.99 1.100 + void print_malloc_line(size_t amount, size_t count) const; 1.101 + void print_virtual_memory_line(size_t reserved, size_t committed) const; 1.102 + void print_arena_line(size_t amount, size_t count) const; 1.103 1.104 - /* 1.105 - * memory summary by memory types. 1.106 - * for each memory type, following summaries are reported: 1.107 - * - reserved amount, committed amount 1.108 - * - malloc'd amount, malloc count 1.109 - * - arena amount, arena count 1.110 - */ 1.111 - 1.112 - // start reporting memory summary by memory type 1.113 - virtual void start_category_summary() = 0; 1.114 - 1.115 - virtual void category_summary(MEMFLAGS type, size_t reserved_amt, 1.116 - size_t committed_amt, 1.117 - size_t malloc_amt, size_t malloc_count, 1.118 - size_t arena_amt, size_t arena_count) = 0; 1.119 - 1.120 - virtual void diff_category_summary(MEMFLAGS type, size_t cur_reserved_amt, 1.121 - size_t cur_committed_amt, 1.122 - size_t cur_malloc_amt, size_t cur_malloc_count, 1.123 - size_t cur_arena_amt, size_t cur_arena_count, 1.124 - int reserved_diff, int committed_diff, int malloc_diff, 1.125 - int malloc_count_diff, int arena_diff, 1.126 - int arena_count_diff) = 0; 1.127 - 1.128 - virtual void done_category_summary() = 0; 1.129 - 1.130 - virtual void start_virtual_memory_map() = 0; 1.131 - virtual void reserved_memory_region(MEMFLAGS type, address base, address end, size_t size, address pc) = 0; 1.132 - virtual void committed_memory_region(address base, address end, size_t size, address pc) = 0; 1.133 - virtual void done_virtual_memory_map() = 0; 1.134 - 1.135 - /* 1.136 - * Report callsite information 1.137 - */ 1.138 - virtual void start_callsite() = 0; 1.139 - virtual void malloc_callsite(address pc, size_t malloc_amt, size_t malloc_count) = 0; 1.140 - virtual void virtual_memory_callsite(address pc, size_t reserved_amt, size_t committed_amt) = 0; 1.141 - 1.142 - virtual void diff_malloc_callsite(address pc, size_t cur_malloc_amt, size_t cur_malloc_count, 1.143 - int malloc_diff, int malloc_count_diff) = 0; 1.144 - virtual void diff_virtual_memory_callsite(address pc, size_t cur_reserved_amt, size_t cur_committed_amt, 1.145 - int reserved_diff, int committed_diff) = 0; 1.146 - 1.147 - virtual void done_callsite() = 0; 1.148 - 1.149 - // return current scale in "KB", "MB" or "GB" 1.150 - static const char* memory_unit(size_t scale); 1.151 + void print_virtual_memory_region(const char* type, address base, size_t size) const; 1.152 }; 1.153 1.154 /* 1.155 - * This class reports processed data from a baseline or 1.156 - * the changes between the two baseline. 1.157 + * The class is for generating summary tracking report. 1.158 */ 1.159 -class BaselineReporter : public StackObj { 1.160 +class MemSummaryReporter : public MemReporterBase { 1.161 private: 1.162 - BaselineOutputer& _outputer; 1.163 - size_t _scale; 1.164 + MallocMemorySnapshot* _malloc_snapshot; 1.165 + VirtualMemorySnapshot* _vm_snapshot; 1.166 + size_t _class_count; 1.167 1.168 public: 1.169 - // construct a reporter that reports memory usage 1.170 - // in specified scale 1.171 - BaselineReporter(BaselineOutputer& outputer, size_t scale = K): 1.172 - _outputer(outputer) { 1.173 - _scale = scale; 1.174 + // Report summary tracking data from global snapshots directly. 1.175 + // This constructor is used for final reporting and hs_err reporting. 1.176 + MemSummaryReporter(MallocMemorySnapshot* malloc_snapshot, 1.177 + VirtualMemorySnapshot* vm_snapshot, outputStream* output, 1.178 + size_t class_count = 0, size_t scale = K) : 1.179 + MemReporterBase(output, scale), 1.180 + _malloc_snapshot(malloc_snapshot), 1.181 + _vm_snapshot(vm_snapshot) { 1.182 + if (class_count == 0) { 1.183 + _class_count = InstanceKlass::number_of_instance_classes(); 1.184 + } else { 1.185 + _class_count = class_count; 1.186 + } 1.187 } 1.188 - virtual void report_baseline(const MemBaseline& baseline, bool summary_only = false); 1.189 - virtual void diff_baselines(const MemBaseline& cur, const MemBaseline& prev, 1.190 - bool summary_only = false); 1.191 + // This constructor is for normal reporting from a recent baseline. 1.192 + MemSummaryReporter(MemBaseline& baseline, outputStream* output, 1.193 + size_t scale = K) : MemReporterBase(output, scale), 1.194 + _malloc_snapshot(baseline.malloc_memory_snapshot()), 1.195 + _vm_snapshot(baseline.virtual_memory_snapshot()), 1.196 + _class_count(baseline.class_count()) { } 1.197 1.198 - void set_scale(size_t scale); 1.199 - size_t scale() const { return _scale; } 1.200 1.201 + // Generate summary report 1.202 + virtual void report(); 1.203 private: 1.204 - void report_summaries(const MemBaseline& baseline); 1.205 - void report_virtual_memory_map(const MemBaseline& baseline); 1.206 - void report_callsites(const MemBaseline& baseline); 1.207 - 1.208 - void diff_summaries(const MemBaseline& cur, const MemBaseline& prev); 1.209 - void diff_callsites(const MemBaseline& cur, const MemBaseline& prev); 1.210 - 1.211 - // calculate memory size in current memory scale 1.212 - size_t amount_in_current_scale(size_t amt) const; 1.213 - // diff two unsigned values in current memory scale 1.214 - int diff_in_current_scale(size_t value1, size_t value2) const; 1.215 - // diff two unsigned value 1.216 - int diff(size_t value1, size_t value2) const; 1.217 + // Report summary for each memory type 1.218 + void report_summary_of_type(MEMFLAGS type, MallocMemory* malloc_memory, 1.219 + VirtualMemory* virtual_memory); 1.220 }; 1.221 1.222 /* 1.223 - * tty output implementation. Native memory tracking 1.224 - * DCmd uses this outputer. 1.225 + * The class is for generating detail tracking report. 1.226 */ 1.227 -class BaselineTTYOutputer : public BaselineOutputer { 1.228 +class MemDetailReporter : public MemSummaryReporter { 1.229 private: 1.230 - size_t _scale; 1.231 - 1.232 - size_t _num_of_classes; 1.233 - size_t _num_of_threads; 1.234 - size_t _thread_stack_reserved; 1.235 - size_t _thread_stack_committed; 1.236 - 1.237 - int _num_of_classes_diff; 1.238 - int _num_of_threads_diff; 1.239 - int _thread_stack_reserved_diff; 1.240 - int _thread_stack_committed_diff; 1.241 - 1.242 - outputStream* _output; 1.243 + MemBaseline& _baseline; 1.244 1.245 public: 1.246 - BaselineTTYOutputer(outputStream* st) { 1.247 - _scale = K; 1.248 - _num_of_classes = 0; 1.249 - _num_of_threads = 0; 1.250 - _thread_stack_reserved = 0; 1.251 - _thread_stack_committed = 0; 1.252 - _num_of_classes_diff = 0; 1.253 - _num_of_threads_diff = 0; 1.254 - _thread_stack_reserved_diff = 0; 1.255 - _thread_stack_committed_diff = 0; 1.256 - _output = st; 1.257 + MemDetailReporter(MemBaseline& baseline, outputStream* output, size_t scale = K) : 1.258 + MemSummaryReporter(baseline, output, scale), 1.259 + _baseline(baseline) { } 1.260 + 1.261 + // Generate detail report. 1.262 + // The report contains summary and detail sections. 1.263 + virtual void report() { 1.264 + MemSummaryReporter::report(); 1.265 + report_virtual_memory_map(); 1.266 + report_detail(); 1.267 } 1.268 1.269 - // begin reporting memory usage in specified scale 1.270 - void start(size_t scale, bool report_diff = false); 1.271 - // done reporting 1.272 - void done(); 1.273 + private: 1.274 + // Report detail tracking data. 1.275 + void report_detail(); 1.276 + // Report virtual memory map 1.277 + void report_virtual_memory_map(); 1.278 + // Report malloc allocation sites 1.279 + void report_malloc_sites(); 1.280 + // Report virtual memory reservation sites 1.281 + void report_virtual_memory_allocation_sites(); 1.282 1.283 - // total memory usage 1.284 - void total_usage(size_t total_reserved, 1.285 - size_t total_committed); 1.286 - // report total loaded classes 1.287 - void num_of_classes(size_t classes) { 1.288 - _num_of_classes = classes; 1.289 + // Report a virtual memory region 1.290 + void report_virtual_memory_region(const ReservedMemoryRegion* rgn); 1.291 +}; 1.292 + 1.293 +/* 1.294 + * The class is for generating summary comparison report. 1.295 + * It compares current memory baseline against an early baseline. 1.296 + */ 1.297 +class MemSummaryDiffReporter : public MemReporterBase { 1.298 + protected: 1.299 + MemBaseline& _early_baseline; 1.300 + MemBaseline& _current_baseline; 1.301 + 1.302 + public: 1.303 + MemSummaryDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline, 1.304 + outputStream* output, size_t scale = K) : MemReporterBase(output, scale), 1.305 + _early_baseline(early_baseline), _current_baseline(current_baseline) { 1.306 + assert(early_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined"); 1.307 + assert(current_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined"); 1.308 } 1.309 1.310 - void num_of_threads(size_t threads) { 1.311 - _num_of_threads = threads; 1.312 - } 1.313 + // Generate summary comparison report 1.314 + virtual void report_diff(); 1.315 1.316 - void thread_info(size_t stack_reserved_amt, size_t stack_committed_amt) { 1.317 - _thread_stack_reserved = stack_reserved_amt; 1.318 - _thread_stack_committed = stack_committed_amt; 1.319 - } 1.320 + private: 1.321 + // report the comparison of each memory type 1.322 + void diff_summary_of_type(MEMFLAGS type, 1.323 + const MallocMemory* early_malloc, const VirtualMemory* early_vm, 1.324 + const MallocMemory* current_malloc, const VirtualMemory* current_vm) const; 1.325 1.326 - void diff_total_usage(size_t total_reserved, 1.327 - size_t total_committed, 1.328 - int reserved_diff, 1.329 - int committed_diff); 1.330 - 1.331 - void diff_num_of_classes(size_t classes, int diff) { 1.332 - _num_of_classes = classes; 1.333 - _num_of_classes_diff = diff; 1.334 - } 1.335 - 1.336 - void diff_num_of_threads(size_t threads, int diff) { 1.337 - _num_of_threads = threads; 1.338 - _num_of_threads_diff = diff; 1.339 - } 1.340 - 1.341 - void diff_thread_info(size_t stack_reserved_amt, size_t stack_committed_amt, 1.342 - int stack_reserved_diff, int stack_committed_diff) { 1.343 - _thread_stack_reserved = stack_reserved_amt; 1.344 - _thread_stack_committed = stack_committed_amt; 1.345 - _thread_stack_reserved_diff = stack_reserved_diff; 1.346 - _thread_stack_committed_diff = stack_committed_diff; 1.347 - } 1.348 - 1.349 - /* 1.350 - * Report memory summary categoriuzed by memory types. 1.351 - * For each memory type, following summaries are reported: 1.352 - * - reserved amount, committed amount 1.353 - * - malloc-ed amount, malloc count 1.354 - * - arena amount, arena count 1.355 - */ 1.356 - // start reporting memory summary by memory type 1.357 - void start_category_summary(); 1.358 - void category_summary(MEMFLAGS type, size_t reserved_amt, size_t committed_amt, 1.359 - size_t malloc_amt, size_t malloc_count, 1.360 - size_t arena_amt, size_t arena_count); 1.361 - 1.362 - void diff_category_summary(MEMFLAGS type, size_t cur_reserved_amt, 1.363 - size_t cur_committed_amt, 1.364 - size_t cur_malloc_amt, size_t cur_malloc_count, 1.365 - size_t cur_arena_amt, size_t cur_arena_count, 1.366 - int reserved_diff, int committed_diff, int malloc_diff, 1.367 - int malloc_count_diff, int arena_diff, 1.368 - int arena_count_diff); 1.369 - 1.370 - void done_category_summary(); 1.371 - 1.372 - // virtual memory map 1.373 - void start_virtual_memory_map(); 1.374 - void reserved_memory_region(MEMFLAGS type, address base, address end, size_t size, address pc); 1.375 - void committed_memory_region(address base, address end, size_t size, address pc); 1.376 - void done_virtual_memory_map(); 1.377 - 1.378 - 1.379 - /* 1.380 - * Report callsite information 1.381 - */ 1.382 - void start_callsite(); 1.383 - void malloc_callsite(address pc, size_t malloc_amt, size_t malloc_count); 1.384 - void virtual_memory_callsite(address pc, size_t reserved_amt, size_t committed_amt); 1.385 - 1.386 - void diff_malloc_callsite(address pc, size_t cur_malloc_amt, size_t cur_malloc_count, 1.387 - int malloc_diff, int malloc_count_diff); 1.388 - void diff_virtual_memory_callsite(address pc, size_t cur_reserved_amt, size_t cur_committed_amt, 1.389 - int reserved_diff, int committed_diff); 1.390 - 1.391 - void done_callsite(); 1.392 + protected: 1.393 + void print_malloc_diff(size_t current_amount, size_t current_count, 1.394 + size_t early_amount, size_t early_count) const; 1.395 + void print_virtual_memory_diff(size_t current_reserved, size_t current_committed, 1.396 + size_t early_reserved, size_t early_committed) const; 1.397 + void print_arena_diff(size_t current_amount, size_t current_count, 1.398 + size_t early_amount, size_t early_count) const; 1.399 }; 1.400 1.401 +/* 1.402 + * The class is for generating detail comparison report. 1.403 + * It compares current memory baseline against an early baseline, 1.404 + * both baselines have to be detail baseline. 1.405 + */ 1.406 +class MemDetailDiffReporter : public MemSummaryDiffReporter { 1.407 + public: 1.408 + MemDetailDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline, 1.409 + outputStream* output, size_t scale = K) : 1.410 + MemSummaryDiffReporter(early_baseline, current_baseline, output, scale) { } 1.411 + 1.412 + // Generate detail comparison report 1.413 + virtual void report_diff(); 1.414 + 1.415 + // Malloc allocation site comparison 1.416 + void diff_malloc_sites() const; 1.417 + // Virutal memory reservation site comparison 1.418 + void diff_virtual_memory_sites() const; 1.419 + 1.420 + // New malloc allocation site in recent baseline 1.421 + void new_malloc_site (const MallocSite* site) const; 1.422 + // The malloc allocation site is not in recent baseline 1.423 + void old_malloc_site (const MallocSite* site) const; 1.424 + // Compare malloc allocation site, it is in both baselines 1.425 + void diff_malloc_site(const MallocSite* early, const MallocSite* current) const; 1.426 + 1.427 + // New virtual memory allocation site in recent baseline 1.428 + void new_virtual_memory_site (const VirtualMemoryAllocationSite* callsite) const; 1.429 + // The virtual memory allocation site is not in recent baseline 1.430 + void old_virtual_memory_site (const VirtualMemoryAllocationSite* callsite) const; 1.431 + // Compare virtual memory allocation site, it is in both baseline 1.432 + void diff_virtual_memory_site(const VirtualMemoryAllocationSite* early, 1.433 + const VirtualMemoryAllocationSite* current) const; 1.434 + 1.435 + void diff_malloc_site(const NativeCallStack* stack, size_t current_size, 1.436 + size_t currrent_count, size_t early_size, size_t early_count) const; 1.437 + void diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved, 1.438 + size_t current_committed, size_t early_reserved, size_t early_committed) const; 1.439 +}; 1.440 1.441 #endif // INCLUDE_NMT 1.442 1.443 -#endif // SHARE_VM_SERVICES_MEM_REPORTER_HPP 1.444 +#endif 1.445 +