1 /* 2 * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_VM_SERVICES_MEM_REPORTER_HPP 26 #define SHARE_VM_SERVICES_MEM_REPORTER_HPP 27 28 #if INCLUDE_NMT 29 30 #include "oops/instanceKlass.hpp" 31 #include "services/memBaseline.hpp" 32 #include "services/nmtCommon.hpp" 33 #include "services/mallocTracker.hpp" 34 #include "services/virtualMemoryTracker.hpp" 35 36 /* 37 * Base class that provides helpers 38 */ 39 class MemReporterBase : public StackObj { 40 private: 41 size_t _scale; // report in this scale 42 outputStream* _output; // destination 43 44 public: 45 MemReporterBase(outputStream* out = NULL, size_t scale = K) 46 : _scale(scale) { 47 _output = (out == NULL) ? tty : out; 48 } 49 50 protected: 51 inline outputStream* output() const { 52 return _output; 53 } 54 // Current reporting scale 55 inline const char* current_scale() const { 56 return NMTUtil::scale_name(_scale); 57 } 58 // Convert memory amount in bytes to current reporting scale 59 inline size_t amount_in_current_scale(size_t amount) const { 60 return NMTUtil::amount_in_scale(amount, _scale); 61 } 62 63 // Convert diff amount in bytes to current reporting scale 64 inline long diff_in_current_scale(size_t s1, size_t s2) const { 65 long amount = (long)(s1 - s2); 66 long scale = (long)_scale; 67 amount = (amount > 0) ? (amount + scale / 2) : (amount - scale / 2); 68 return amount / scale; 69 } 70 71 // Helper functions 72 // Calculate total reserved and committed amount 73 size_t reserved_total(const MallocMemory* malloc, const VirtualMemory* vm) const; 74 size_t committed_total(const MallocMemory* malloc, const VirtualMemory* vm) const; 75 76 77 // Print summary total, malloc and virtual memory 78 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 void print_virtual_memory(size_t reserved, size_t committed) const; 81 82 void print_malloc_line(size_t amount, size_t count) const; 83 void print_virtual_memory_line(size_t reserved, size_t committed) const; 84 void print_arena_line(size_t amount, size_t count) const; 85 86 void print_virtual_memory_region(const char* type, address base, size_t size) const; 87 }; 88 89 /* 90 * The class is for generating summary tracking report. 91 */ 92 class MemSummaryReporter : public MemReporterBase { 93 private: 94 MallocMemorySnapshot* _malloc_snapshot; 95 VirtualMemorySnapshot* _vm_snapshot; 96 size_t _class_count; 97 98 public: 99 // This constructor is for normal reporting from a recent baseline. 100 MemSummaryReporter(MemBaseline& baseline, outputStream* output, 101 size_t scale = K) : MemReporterBase(output, scale), 102 _malloc_snapshot(baseline.malloc_memory_snapshot()), 103 _vm_snapshot(baseline.virtual_memory_snapshot()), 104 _class_count(baseline.class_count()) { } 105 106 107 // Generate summary report 108 virtual void report(); 109 private: 110 // Report summary for each memory type 111 void report_summary_of_type(MEMFLAGS type, MallocMemory* malloc_memory, 112 VirtualMemory* virtual_memory); 113 }; 114 115 /* 116 * The class is for generating detail tracking report. 117 */ 118 class MemDetailReporter : public MemSummaryReporter { 119 private: 120 MemBaseline& _baseline; 121 122 public: 123 MemDetailReporter(MemBaseline& baseline, outputStream* output, size_t scale = K) : 124 MemSummaryReporter(baseline, output, scale), 125 _baseline(baseline) { } 126 127 // Generate detail report. 128 // The report contains summary and detail sections. 129 virtual void report() { 130 MemSummaryReporter::report(); 131 report_virtual_memory_map(); 132 report_detail(); 133 } 134 135 private: 136 // Report detail tracking data. 137 void report_detail(); 138 // Report virtual memory map 139 void report_virtual_memory_map(); 140 // Report malloc allocation sites 141 void report_malloc_sites(); 142 // Report virtual memory reservation sites 143 void report_virtual_memory_allocation_sites(); 144 145 // Report a virtual memory region 146 void report_virtual_memory_region(const ReservedMemoryRegion* rgn); 147 }; 148 149 /* 150 * The class is for generating summary comparison report. 151 * It compares current memory baseline against an early baseline. 152 */ 153 class MemSummaryDiffReporter : public MemReporterBase { 154 protected: 155 MemBaseline& _early_baseline; 156 MemBaseline& _current_baseline; 157 158 public: 159 MemSummaryDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline, 160 outputStream* output, size_t scale = K) : MemReporterBase(output, scale), 161 _early_baseline(early_baseline), _current_baseline(current_baseline) { 162 assert(early_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined"); 163 assert(current_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined"); 164 } 165 166 // Generate summary comparison report 167 virtual void report_diff(); 168 169 private: 170 // report the comparison of each memory type 171 void diff_summary_of_type(MEMFLAGS type, 172 const MallocMemory* early_malloc, const VirtualMemory* early_vm, 173 const MallocMemory* current_malloc, const VirtualMemory* current_vm) const; 174 175 protected: 176 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 void print_virtual_memory_diff(size_t current_reserved, size_t current_committed, 179 size_t early_reserved, size_t early_committed) const; 180 void print_arena_diff(size_t current_amount, size_t current_count, 181 size_t early_amount, size_t early_count) const; 182 }; 183 184 /* 185 * The class is for generating detail comparison report. 186 * It compares current memory baseline against an early baseline, 187 * both baselines have to be detail baseline. 188 */ 189 class MemDetailDiffReporter : public MemSummaryDiffReporter { 190 public: 191 MemDetailDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline, 192 outputStream* output, size_t scale = K) : 193 MemSummaryDiffReporter(early_baseline, current_baseline, output, scale) { } 194 195 // Generate detail comparison report 196 virtual void report_diff(); 197 198 // Malloc allocation site comparison 199 void diff_malloc_sites() const; 200 // Virutal memory reservation site comparison 201 void diff_virtual_memory_sites() const; 202 203 // New malloc allocation site in recent baseline 204 void new_malloc_site (const MallocSite* site) const; 205 // The malloc allocation site is not in recent baseline 206 void old_malloc_site (const MallocSite* site) const; 207 // Compare malloc allocation site, it is in both baselines 208 void diff_malloc_site(const MallocSite* early, const MallocSite* current) const; 209 210 // New virtual memory allocation site in recent baseline 211 void new_virtual_memory_site (const VirtualMemoryAllocationSite* callsite) const; 212 // The virtual memory allocation site is not in recent baseline 213 void old_virtual_memory_site (const VirtualMemoryAllocationSite* callsite) const; 214 // Compare virtual memory allocation site, it is in both baseline 215 void diff_virtual_memory_site(const VirtualMemoryAllocationSite* early, 216 const VirtualMemoryAllocationSite* current) const; 217 218 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 }; 223 224 #endif // INCLUDE_NMT 225 226 #endif 227