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_MEMBASELINE_HPP |
26 | #define SHARE_SERVICES_MEMBASELINE_HPP |
27 | |
28 | #if INCLUDE_NMT |
29 | |
30 | #include "runtime/mutex.hpp" |
31 | #include "services/mallocSiteTable.hpp" |
32 | #include "services/mallocTracker.hpp" |
33 | #include "services/nmtCommon.hpp" |
34 | #include "services/virtualMemoryTracker.hpp" |
35 | #include "utilities/linkedlist.hpp" |
36 | |
37 | typedef LinkedListIterator<MallocSite> MallocSiteIterator; |
38 | typedef LinkedListIterator<VirtualMemoryAllocationSite> VirtualMemorySiteIterator; |
39 | typedef LinkedListIterator<ReservedMemoryRegion> VirtualMemoryAllocationIterator; |
40 | |
41 | /* |
42 | * Baseline a memory snapshot |
43 | */ |
44 | class MemBaseline { |
45 | public: |
46 | enum BaselineThreshold { |
47 | SIZE_THRESHOLD = K // Only allocation size over this threshold will be baselined. |
48 | }; |
49 | |
50 | enum BaselineType { |
51 | Not_baselined, |
52 | Summary_baselined, |
53 | Detail_baselined |
54 | }; |
55 | |
56 | enum SortingOrder { |
57 | by_address, // by memory address |
58 | by_size, // by memory size |
59 | by_site, // by call site where the memory is allocated from |
60 | by_site_and_type // by call site and memory type |
61 | }; |
62 | |
63 | private: |
64 | // Summary information |
65 | MallocMemorySnapshot _malloc_memory_snapshot; |
66 | VirtualMemorySnapshot _virtual_memory_snapshot; |
67 | MetaspaceSnapshot _metaspace_snapshot; |
68 | |
69 | size_t _instance_class_count; |
70 | size_t _array_class_count; |
71 | |
72 | // Allocation sites information |
73 | // Malloc allocation sites |
74 | LinkedListImpl<MallocSite> _malloc_sites; |
75 | |
76 | // All virtual memory allocations |
77 | LinkedListImpl<ReservedMemoryRegion> _virtual_memory_allocations; |
78 | |
79 | // Virtual memory allocations by allocation sites, always in by_address |
80 | // order |
81 | LinkedListImpl<VirtualMemoryAllocationSite> _virtual_memory_sites; |
82 | |
83 | SortingOrder _malloc_sites_order; |
84 | SortingOrder _virtual_memory_sites_order; |
85 | |
86 | BaselineType _baseline_type; |
87 | |
88 | public: |
89 | // create a memory baseline |
90 | MemBaseline(): |
91 | _instance_class_count(0), _array_class_count(0), |
92 | _baseline_type(Not_baselined) { |
93 | } |
94 | |
95 | bool baseline(bool summaryOnly = true); |
96 | |
97 | BaselineType baseline_type() const { return _baseline_type; } |
98 | |
99 | MallocMemorySnapshot* malloc_memory_snapshot() { |
100 | return &_malloc_memory_snapshot; |
101 | } |
102 | |
103 | VirtualMemorySnapshot* virtual_memory_snapshot() { |
104 | return &_virtual_memory_snapshot; |
105 | } |
106 | |
107 | MetaspaceSnapshot* metaspace_snapshot() { |
108 | return &_metaspace_snapshot; |
109 | } |
110 | |
111 | MallocSiteIterator malloc_sites(SortingOrder order); |
112 | VirtualMemorySiteIterator virtual_memory_sites(SortingOrder order); |
113 | |
114 | // Virtual memory allocation iterator always returns in virtual memory |
115 | // base address order. |
116 | VirtualMemoryAllocationIterator virtual_memory_allocations() { |
117 | assert(!_virtual_memory_allocations.is_empty(), "Not detail baseline" ); |
118 | return VirtualMemoryAllocationIterator(_virtual_memory_allocations.head()); |
119 | } |
120 | |
121 | // Total reserved memory = total malloc'd memory + total reserved virtual |
122 | // memory |
123 | size_t total_reserved_memory() const { |
124 | assert(baseline_type() != Not_baselined, "Not yet baselined" ); |
125 | size_t amount = _malloc_memory_snapshot.total() + |
126 | _virtual_memory_snapshot.total_reserved(); |
127 | return amount; |
128 | } |
129 | |
130 | // Total committed memory = total malloc'd memory + total committed |
131 | // virtual memory |
132 | size_t total_committed_memory() const { |
133 | assert(baseline_type() != Not_baselined, "Not yet baselined" ); |
134 | size_t amount = _malloc_memory_snapshot.total() + |
135 | _virtual_memory_snapshot.total_committed(); |
136 | return amount; |
137 | } |
138 | |
139 | size_t total_arena_memory() const { |
140 | assert(baseline_type() != Not_baselined, "Not yet baselined" ); |
141 | return _malloc_memory_snapshot.total_arena(); |
142 | } |
143 | |
144 | size_t malloc_tracking_overhead() const { |
145 | assert(baseline_type() != Not_baselined, "Not yet baselined" ); |
146 | MemBaseline* bl = const_cast<MemBaseline*>(this); |
147 | return bl->_malloc_memory_snapshot.malloc_overhead()->size(); |
148 | } |
149 | |
150 | MallocMemory* malloc_memory(MEMFLAGS flag) { |
151 | assert(baseline_type() != Not_baselined, "Not yet baselined" ); |
152 | return _malloc_memory_snapshot.by_type(flag); |
153 | } |
154 | |
155 | VirtualMemory* virtual_memory(MEMFLAGS flag) { |
156 | assert(baseline_type() != Not_baselined, "Not yet baselined" ); |
157 | return _virtual_memory_snapshot.by_type(flag); |
158 | } |
159 | |
160 | |
161 | size_t class_count() const { |
162 | assert(baseline_type() != Not_baselined, "Not yet baselined" ); |
163 | return _instance_class_count + _array_class_count; |
164 | } |
165 | |
166 | size_t instance_class_count() const { |
167 | assert(baseline_type() != Not_baselined, "Not yet baselined" ); |
168 | return _instance_class_count; |
169 | } |
170 | |
171 | size_t array_class_count() const { |
172 | assert(baseline_type() != Not_baselined, "Not yet baselined" ); |
173 | return _array_class_count; |
174 | } |
175 | |
176 | size_t thread_count() const { |
177 | assert(baseline_type() != Not_baselined, "Not yet baselined" ); |
178 | return _malloc_memory_snapshot.thread_count(); |
179 | } |
180 | |
181 | // reset the baseline for reuse |
182 | void reset() { |
183 | _baseline_type = Not_baselined; |
184 | // _malloc_memory_snapshot and _virtual_memory_snapshot are copied over. |
185 | _instance_class_count = 0; |
186 | _array_class_count = 0; |
187 | |
188 | _malloc_sites.clear(); |
189 | _virtual_memory_sites.clear(); |
190 | _virtual_memory_allocations.clear(); |
191 | } |
192 | |
193 | private: |
194 | // Baseline summary information |
195 | bool baseline_summary(); |
196 | |
197 | // Baseline allocation sites (detail tracking only) |
198 | bool baseline_allocation_sites(); |
199 | |
200 | // Aggregate virtual memory allocation by allocation sites |
201 | bool aggregate_virtual_memory_allocation_sites(); |
202 | |
203 | // Sorting allocation sites in different orders |
204 | // Sort allocation sites in size order |
205 | void malloc_sites_to_size_order(); |
206 | // Sort allocation sites in call site address order |
207 | void malloc_sites_to_allocation_site_order(); |
208 | // Sort allocation sites in call site address and memory type order |
209 | void malloc_sites_to_allocation_site_and_type_order(); |
210 | |
211 | // Sort allocation sites in reserved size order |
212 | void virtual_memory_sites_to_size_order(); |
213 | // Sort allocation sites in call site address order |
214 | void virtual_memory_sites_to_reservation_site_order(); |
215 | }; |
216 | |
217 | #endif // INCLUDE_NMT |
218 | |
219 | #endif // SHARE_SERVICES_MEMBASELINE_HPP |
220 | |