memReporter.hpp 8.1 KB
Newer Older
Z
zgu 已提交
1
/*
2
 * Copyright (c) 2012, 2017, 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
  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;
79
  void print_malloc(size_t amount, size_t count, MEMFLAGS flag = mtNone) const;
80 81 82 83 84 85 86
  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
  // 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 已提交
105 106


107 108
  // Generate summary report
  virtual void report();
Z
zgu 已提交
109
 private:
110 111 112
  // Report summary for each memory type
  void report_summary_of_type(MEMFLAGS type, MallocMemory* malloc_memory,
    VirtualMemory* virtual_memory);
Z
zgu 已提交
113 114 115
};

/*
116
 * The class is for generating detail tracking report.
Z
zgu 已提交
117
 */
118
class MemDetailReporter : public MemSummaryReporter {
Z
zgu 已提交
119
 private:
120
  MemBaseline&   _baseline;
Z
zgu 已提交
121 122

 public:
123 124 125 126 127 128 129 130 131 132
  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 已提交
133 134
  }

135 136 137 138 139 140 141 142 143 144 145 146 147
 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 已提交
148

149 150 151 152 153 154 155 156
/*
 * 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 已提交
157

158 159 160 161 162 163
 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 已提交
164 165
  }

166 167
  // Generate summary comparison report
  virtual void report_diff();
Z
zgu 已提交
168

169 170 171 172 173 174 175 176
 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,
177
    size_t early_amount, size_t early_count, MEMFLAGS flags) const;
178 179 180 181
  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 已提交
182 183
};

184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
/*
 * 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,
219
    size_t currrent_count, size_t early_size, size_t early_count, MEMFLAGS flags) const;
220
  void diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved,
221
    size_t current_committed, size_t early_reserved, size_t early_committed, MEMFLAGS flag) const;
222
};
Z
zgu 已提交
223

224 225
#endif // INCLUDE_NMT

226 227
#endif