aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm/services/memReporter.hpp
blob: 794804dc2f510095c7413a34619b481fe1894c35 (plain)
1
2
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
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
219
220
221
222
223
224
225
226
227
/*
 * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
 * 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

#if INCLUDE_NMT

#include "oops/instanceKlass.hpp"
#include "services/memBaseline.hpp"
#include "services/nmtCommon.hpp"
#include "services/mallocTracker.hpp"
#include "services/virtualMemoryTracker.hpp"

/*
 * Base class that provides helpers
*/
class MemReporterBase : public StackObj {
 private:
  size_t        _scale;  // report in this scale
  outputStream* _output; // destination

 public:
  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, MEMFLAGS flag = mtNone) 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;
};

/*
 * The class is for generating summary tracking report.
 */
class MemSummaryReporter : public MemReporterBase {
 private:
  MallocMemorySnapshot*   _malloc_snapshot;
  VirtualMemorySnapshot*  _vm_snapshot;
  size_t                  _class_count;

 public:
  // 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()) { }


  // Generate summary report
  virtual void report();
 private:
  // Report summary for each memory type
  void report_summary_of_type(MEMFLAGS type, MallocMemory* malloc_memory,
    VirtualMemory* virtual_memory);
};

/*
 * The class is for generating detail tracking report.
 */
class MemDetailReporter : public MemSummaryReporter {
 private:
  MemBaseline&   _baseline;

 public:
  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();
  }

 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);
};

/*
 * 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;

 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");
  }

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

 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, MEMFLAGS flags) 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;
};

/*
 * 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, MEMFLAGS flags) 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, MEMFLAGS flag) const;
};

#endif // INCLUDE_NMT

#endif