1 /* 2 * Copyright (c) 2012, 2019, 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_SERVICES_MEMREPORTER_HPP 26 #define SHARE_SERVICES_MEMREPORTER_HPP 27 28 #if INCLUDE_NMT 29 30 #include "memory/metaspace.hpp" 31 #include "oops/instanceKlass.hpp" 32 #include "services/memBaseline.hpp" 33 #include "services/nmtCommon.hpp" 34 #include "services/mallocTracker.hpp" 35 #include "services/virtualMemoryTracker.hpp" 36 37 /* 38 * Base class that provides helpers 39 */ 40 class MemReporterBase : public StackObj { 41 private: 42 const size_t _scale; // report in this scale 43 outputStream* const _output; // destination 44 45 public: 46 47 // Default scale to use if no scale given. 48 static const size_t default_scale = K; 49 MemReporterBase(outputStream * out,size_t scale=default_scale)50 MemReporterBase(outputStream* out, size_t scale = default_scale) : 51 _scale(scale), _output(out) 52 {} 53 54 protected: output() const55 inline outputStream* output() const { 56 return _output; 57 } 58 // Current reporting scale scale() const59 size_t scale() const { 60 return _scale; 61 } current_scale() const62 inline const char* current_scale() const { 63 return NMTUtil::scale_name(_scale); 64 } 65 // Convert memory amount in bytes to current reporting scale amount_in_current_scale(size_t amount) const66 inline size_t amount_in_current_scale(size_t amount) const { 67 return NMTUtil::amount_in_scale(amount, _scale); 68 } 69 70 // Convert diff amount in bytes to current reporting scale diff_in_current_scale(size_t s1,size_t s2) const71 inline long diff_in_current_scale(size_t s1, size_t s2) const { 72 long amount = (long)(s1 - s2); 73 long scale = (long)_scale; 74 amount = (amount > 0) ? (amount + scale / 2) : (amount - scale / 2); 75 return amount / scale; 76 } 77 78 // Helper functions 79 // Calculate total reserved and committed amount 80 size_t reserved_total(const MallocMemory* malloc, const VirtualMemory* vm) const; 81 size_t committed_total(const MallocMemory* malloc, const VirtualMemory* vm) const; 82 83 // Print summary total, malloc and virtual memory 84 void print_total(size_t reserved, size_t committed) const; 85 void print_malloc(size_t amount, size_t count, MEMFLAGS flag = mtNone) const; 86 void print_virtual_memory(size_t reserved, size_t committed) const; 87 88 void print_malloc_line(size_t amount, size_t count) const; 89 void print_virtual_memory_line(size_t reserved, size_t committed) const; 90 void print_arena_line(size_t amount, size_t count) const; 91 92 void print_virtual_memory_region(const char* type, address base, size_t size) const; 93 }; 94 95 /* 96 * The class is for generating summary tracking report. 97 */ 98 class MemSummaryReporter : public MemReporterBase { 99 private: 100 MallocMemorySnapshot* _malloc_snapshot; 101 VirtualMemorySnapshot* _vm_snapshot; 102 size_t _instance_class_count; 103 size_t _array_class_count; 104 105 public: 106 // This constructor is for normal reporting from a recent baseline. MemSummaryReporter(MemBaseline & baseline,outputStream * output,size_t scale=default_scale)107 MemSummaryReporter(MemBaseline& baseline, outputStream* output, 108 size_t scale = default_scale) : MemReporterBase(output, scale), 109 _malloc_snapshot(baseline.malloc_memory_snapshot()), 110 _vm_snapshot(baseline.virtual_memory_snapshot()), 111 _instance_class_count(baseline.instance_class_count()), 112 _array_class_count(baseline.array_class_count()) { } 113 114 115 // Generate summary report 116 virtual void report(); 117 private: 118 // Report summary for each memory type 119 void report_summary_of_type(MEMFLAGS type, MallocMemory* malloc_memory, 120 VirtualMemory* virtual_memory); 121 122 void report_metadata(Metaspace::MetadataType type) const; 123 }; 124 125 /* 126 * The class is for generating detail tracking report. 127 */ 128 class MemDetailReporter : public MemSummaryReporter { 129 private: 130 MemBaseline& _baseline; 131 132 public: MemDetailReporter(MemBaseline & baseline,outputStream * output,size_t scale=default_scale)133 MemDetailReporter(MemBaseline& baseline, outputStream* output, size_t scale = default_scale) : 134 MemSummaryReporter(baseline, output, scale), 135 _baseline(baseline) { } 136 137 // Generate detail report. 138 // The report contains summary and detail sections. report()139 virtual void report() { 140 MemSummaryReporter::report(); 141 report_virtual_memory_map(); 142 report_detail(); 143 } 144 145 private: 146 // Report detail tracking data. 147 void report_detail(); 148 // Report virtual memory map 149 void report_virtual_memory_map(); 150 // Report malloc allocation sites; returns number of omitted sites 151 int report_malloc_sites(); 152 // Report virtual memory reservation sites; returns number of omitted sites 153 int report_virtual_memory_allocation_sites(); 154 155 // Report a virtual memory region 156 void report_virtual_memory_region(const ReservedMemoryRegion* rgn); 157 }; 158 159 /* 160 * The class is for generating summary comparison report. 161 * It compares current memory baseline against an early baseline. 162 */ 163 class MemSummaryDiffReporter : public MemReporterBase { 164 protected: 165 MemBaseline& _early_baseline; 166 MemBaseline& _current_baseline; 167 168 public: MemSummaryDiffReporter(MemBaseline & early_baseline,MemBaseline & current_baseline,outputStream * output,size_t scale=default_scale)169 MemSummaryDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline, 170 outputStream* output, size_t scale = default_scale) : MemReporterBase(output, scale), 171 _early_baseline(early_baseline), _current_baseline(current_baseline) { 172 assert(early_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined"); 173 assert(current_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined"); 174 } 175 176 // Generate summary comparison report 177 virtual void report_diff(); 178 179 private: 180 // report the comparison of each memory type 181 void diff_summary_of_type(MEMFLAGS type, 182 const MallocMemory* early_malloc, const VirtualMemory* early_vm, 183 const MetaspaceCombinedStats& early_ms, 184 const MallocMemory* current_malloc, const VirtualMemory* current_vm, 185 const MetaspaceCombinedStats& current_ms) const; 186 187 protected: 188 void print_malloc_diff(size_t current_amount, size_t current_count, 189 size_t early_amount, size_t early_count, MEMFLAGS flags) const; 190 void print_virtual_memory_diff(size_t current_reserved, size_t current_committed, 191 size_t early_reserved, size_t early_committed) const; 192 void print_arena_diff(size_t current_amount, size_t current_count, 193 size_t early_amount, size_t early_count) const; 194 195 void print_metaspace_diff(const MetaspaceCombinedStats& current_ms, 196 const MetaspaceCombinedStats& early_ms) const; 197 void print_metaspace_diff(const char* header, 198 const MetaspaceStats& current_ms, 199 const MetaspaceStats& early_ms) const; 200 }; 201 202 /* 203 * The class is for generating detail comparison report. 204 * It compares current memory baseline against an early baseline, 205 * both baselines have to be detail baseline. 206 */ 207 class MemDetailDiffReporter : public MemSummaryDiffReporter { 208 public: MemDetailDiffReporter(MemBaseline & early_baseline,MemBaseline & current_baseline,outputStream * output,size_t scale=default_scale)209 MemDetailDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline, 210 outputStream* output, size_t scale = default_scale) : 211 MemSummaryDiffReporter(early_baseline, current_baseline, output, scale) { } 212 213 // Generate detail comparison report 214 virtual void report_diff(); 215 216 // Malloc allocation site comparison 217 void diff_malloc_sites() const; 218 // Virutal memory reservation site comparison 219 void diff_virtual_memory_sites() const; 220 221 // New malloc allocation site in recent baseline 222 void new_malloc_site (const MallocSite* site) const; 223 // The malloc allocation site is not in recent baseline 224 void old_malloc_site (const MallocSite* site) const; 225 // Compare malloc allocation site, it is in both baselines 226 void diff_malloc_site(const MallocSite* early, const MallocSite* current) const; 227 228 // New virtual memory allocation site in recent baseline 229 void new_virtual_memory_site (const VirtualMemoryAllocationSite* callsite) const; 230 // The virtual memory allocation site is not in recent baseline 231 void old_virtual_memory_site (const VirtualMemoryAllocationSite* callsite) const; 232 // Compare virtual memory allocation site, it is in both baseline 233 void diff_virtual_memory_site(const VirtualMemoryAllocationSite* early, 234 const VirtualMemoryAllocationSite* current) const; 235 236 void diff_malloc_site(const NativeCallStack* stack, size_t current_size, 237 size_t currrent_count, size_t early_size, size_t early_count, MEMFLAGS flags) const; 238 void diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved, 239 size_t current_committed, size_t early_reserved, size_t early_committed, MEMFLAGS flag) const; 240 }; 241 242 #endif // INCLUDE_NMT 243 244 #endif // SHARE_SERVICES_MEMREPORTER_HPP 245