memReporter.hpp 8.6 KB
Newer Older
Z
zgu 已提交
1
/*
2
 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
Z
zgu 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_VM_SERVICES_MEM_REPORTER_HPP
#define SHARE_VM_SERVICES_MEM_REPORTER_HPP

28 29
#if INCLUDE_NMT

30 31 32 33 34 35
#include "oops/instanceKlass.hpp"
#include "services/memBaseline.hpp"
#include "services/nmtCommon.hpp"
#include "services/mallocTracker.hpp"
#include "services/virtualMemoryTracker.hpp"

Z
zgu 已提交
36
/*
37 38 39 40 41 42 43
 * Base class that provides helpers
*/
class MemReporterBase : public StackObj {
 private:
  size_t        _scale;  // report in this scale
  outputStream* _output; // destination

Z
zgu 已提交
44
 public:
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
  MemReporterBase(outputStream* out = NULL, size_t scale = K)
    : _scale(scale) {
    _output = (out == NULL) ? tty : out;
  }

 protected:
  inline outputStream* output() const {
    return _output;
  }
  // Current reporting scale
  inline const char* current_scale() const {
    return NMTUtil::scale_name(_scale);
  }
  // Convert memory amount in bytes to current reporting scale
  inline size_t amount_in_current_scale(size_t amount) const {
    return NMTUtil::amount_in_scale(amount, _scale);
  }

  // Convert diff amount in bytes to current reporting scale
  inline long diff_in_current_scale(size_t s1, size_t s2) const {
    long amount = (long)(s1 - s2);
    long scale = (long)_scale;
    amount = (amount > 0) ? (amount + scale / 2) : (amount - scale / 2);
    return amount / scale;
  }

  // Helper functions
  // Calculate total reserved and committed amount
  size_t reserved_total(const MallocMemory* malloc, const VirtualMemory* vm) const;
  size_t committed_total(const MallocMemory* malloc, const VirtualMemory* vm) const;


  // Print summary total, malloc and virtual memory
  void print_total(size_t reserved, size_t committed) const;
  void print_malloc(size_t amount, size_t count) const;
  void print_virtual_memory(size_t reserved, size_t committed) const;

  void print_malloc_line(size_t amount, size_t count) const;
  void print_virtual_memory_line(size_t reserved, size_t committed) const;
  void print_arena_line(size_t amount, size_t count) const;

  void print_virtual_memory_region(const char* type, address base, size_t size) const;
Z
zgu 已提交
87 88 89
};

/*
90
 * The class is for generating summary tracking report.
Z
zgu 已提交
91
 */
92
class MemSummaryReporter : public MemReporterBase {
Z
zgu 已提交
93
 private:
94 95 96
  MallocMemorySnapshot*   _malloc_snapshot;
  VirtualMemorySnapshot*  _vm_snapshot;
  size_t                  _class_count;
Z
zgu 已提交
97 98

 public:
99 100 101 102 103 104 105 106 107 108 109 110 111
  // Report summary tracking data from global snapshots directly.
  // This constructor is used for final reporting and hs_err reporting.
  MemSummaryReporter(MallocMemorySnapshot* malloc_snapshot,
    VirtualMemorySnapshot* vm_snapshot, outputStream* output,
    size_t class_count = 0, size_t scale = K) :
    MemReporterBase(output, scale),
    _malloc_snapshot(malloc_snapshot),
    _vm_snapshot(vm_snapshot) {
    if (class_count == 0) {
      _class_count = InstanceKlass::number_of_instance_classes();
    } else {
      _class_count = class_count;
    }
Z
zgu 已提交
112
  }
113 114 115 116 117 118
  // This constructor is for normal reporting from a recent baseline.
  MemSummaryReporter(MemBaseline& baseline, outputStream* output,
    size_t scale = K) : MemReporterBase(output, scale),
    _malloc_snapshot(baseline.malloc_memory_snapshot()),
    _vm_snapshot(baseline.virtual_memory_snapshot()),
    _class_count(baseline.class_count()) { }
Z
zgu 已提交
119 120


121 122
  // Generate summary report
  virtual void report();
Z
zgu 已提交
123
 private:
124 125 126
  // Report summary for each memory type
  void report_summary_of_type(MEMFLAGS type, MallocMemory* malloc_memory,
    VirtualMemory* virtual_memory);
Z
zgu 已提交
127 128 129
};

/*
130
 * The class is for generating detail tracking report.
Z
zgu 已提交
131
 */
132
class MemDetailReporter : public MemSummaryReporter {
Z
zgu 已提交
133
 private:
134
  MemBaseline&   _baseline;
Z
zgu 已提交
135 136

 public:
137 138 139 140 141 142 143 144 145 146
  MemDetailReporter(MemBaseline& baseline, outputStream* output, size_t scale = K) :
    MemSummaryReporter(baseline, output, scale),
     _baseline(baseline) { }

  // Generate detail report.
  // The report contains summary and detail sections.
  virtual void report() {
    MemSummaryReporter::report();
    report_virtual_memory_map();
    report_detail();
Z
zgu 已提交
147 148
  }

149 150 151 152 153 154 155 156 157 158 159 160 161
 private:
  // Report detail tracking data.
  void report_detail();
  // Report virtual memory map
  void report_virtual_memory_map();
  // Report malloc allocation sites
  void report_malloc_sites();
  // Report virtual memory reservation sites
  void report_virtual_memory_allocation_sites();

  // Report a virtual memory region
  void report_virtual_memory_region(const ReservedMemoryRegion* rgn);
};
Z
zgu 已提交
162

163 164 165 166 167 168 169 170
/*
 * The class is for generating summary comparison report.
 * It compares current memory baseline against an early baseline.
 */
class MemSummaryDiffReporter : public MemReporterBase {
 protected:
  MemBaseline&      _early_baseline;
  MemBaseline&      _current_baseline;
Z
zgu 已提交
171

172 173 174 175 176 177
 public:
  MemSummaryDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline,
    outputStream* output, size_t scale = K) : MemReporterBase(output, scale),
    _early_baseline(early_baseline), _current_baseline(current_baseline) {
    assert(early_baseline.baseline_type()   != MemBaseline::Not_baselined, "Not baselined");
    assert(current_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined");
Z
zgu 已提交
178 179
  }

180 181
  // Generate summary comparison report
  virtual void report_diff();
Z
zgu 已提交
182

183 184 185 186 187 188 189 190 191 192 193 194 195
 private:
  // report the comparison of each memory type
  void diff_summary_of_type(MEMFLAGS type,
    const MallocMemory* early_malloc, const VirtualMemory* early_vm,
    const MallocMemory* current_malloc, const VirtualMemory* current_vm) const;

 protected:
  void print_malloc_diff(size_t current_amount, size_t current_count,
    size_t early_amount, size_t early_count) const;
  void print_virtual_memory_diff(size_t current_reserved, size_t current_committed,
    size_t early_reserved, size_t early_committed) const;
  void print_arena_diff(size_t current_amount, size_t current_count,
    size_t early_amount, size_t early_count) const;
Z
zgu 已提交
196 197
};

198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
/*
 * The class is for generating detail comparison report.
 * It compares current memory baseline against an early baseline,
 * both baselines have to be detail baseline.
 */
class MemDetailDiffReporter : public MemSummaryDiffReporter {
 public:
  MemDetailDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline,
    outputStream* output, size_t scale = K) :
    MemSummaryDiffReporter(early_baseline, current_baseline, output, scale) { }

  // Generate detail comparison report
  virtual void report_diff();

  // Malloc allocation site comparison
  void diff_malloc_sites() const;
  // Virutal memory reservation site comparison
  void diff_virtual_memory_sites() const;

  // New malloc allocation site in recent baseline
  void new_malloc_site (const MallocSite* site) const;
  // The malloc allocation site is not in recent baseline
  void old_malloc_site (const MallocSite* site) const;
  // Compare malloc allocation site, it is in both baselines
  void diff_malloc_site(const MallocSite* early, const MallocSite* current)  const;

  // New virtual memory allocation site in recent baseline
  void new_virtual_memory_site (const VirtualMemoryAllocationSite* callsite) const;
  // The virtual memory allocation site is not in recent baseline
  void old_virtual_memory_site (const VirtualMemoryAllocationSite* callsite) const;
  // Compare virtual memory allocation site, it is in both baseline
  void diff_virtual_memory_site(const VirtualMemoryAllocationSite* early,
                                const VirtualMemoryAllocationSite* current)  const;

  void diff_malloc_site(const NativeCallStack* stack, size_t current_size,
    size_t currrent_count, size_t early_size, size_t early_count) const;
  void diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved,
    size_t current_committed, size_t early_reserved, size_t early_committed) const;
};
Z
zgu 已提交
237

238 239
#endif // INCLUDE_NMT

240 241
#endif