src/share/vm/services/memReporter.hpp

changeset 7074
833b0f92429a
parent 6198
55fb97c4c58d
child 7267
417e3b8d04c5
     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 +

mercurial