Mercurial > hg > graal-jvmci-8
comparison src/share/vm/services/memBaseline.cpp @ 20366:dd3939fe8424
8054546: NMT2 leaks memory
Summary: Fixed memory leak in NMT by baselining memory in c heap instead of an arena.
Reviewed-by: coleenp, minqi
author | zgu |
---|---|
date | Wed, 20 Aug 2014 08:41:15 -0400 |
parents | 833b0f92429a |
children |
comparison
equal
deleted
inserted
replaced
20365:3adc0e278f49 | 20366:dd3939fe8424 |
---|---|
68 /* | 68 /* |
69 * Walker to walk malloc allocation site table | 69 * Walker to walk malloc allocation site table |
70 */ | 70 */ |
71 class MallocAllocationSiteWalker : public MallocSiteWalker { | 71 class MallocAllocationSiteWalker : public MallocSiteWalker { |
72 private: | 72 private: |
73 SortedLinkedList<MallocSite, compare_malloc_size, ResourceObj::ARENA> | 73 SortedLinkedList<MallocSite, compare_malloc_size> _malloc_sites; |
74 _malloc_sites; | |
75 size_t _count; | 74 size_t _count; |
76 | 75 |
77 // Entries in MallocSiteTable with size = 0 and count = 0, | 76 // Entries in MallocSiteTable with size = 0 and count = 0, |
78 // when the malloc site is not longer there. | 77 // when the malloc site is not longer there. |
79 public: | 78 public: |
80 MallocAllocationSiteWalker(Arena* arena) : _count(0), _malloc_sites(arena) { | 79 MallocAllocationSiteWalker() : _count(0) { } |
81 } | |
82 | 80 |
83 inline size_t count() const { return _count; } | 81 inline size_t count() const { return _count; } |
84 | 82 |
85 LinkedList<MallocSite>* malloc_sites() { | 83 LinkedList<MallocSite>* malloc_sites() { |
86 return &_malloc_sites; | 84 return &_malloc_sites; |
107 } | 105 } |
108 | 106 |
109 // Walk all virtual memory regions for baselining | 107 // Walk all virtual memory regions for baselining |
110 class VirtualMemoryAllocationWalker : public VirtualMemoryWalker { | 108 class VirtualMemoryAllocationWalker : public VirtualMemoryWalker { |
111 private: | 109 private: |
112 SortedLinkedList<ReservedMemoryRegion, compare_virtual_memory_base, ResourceObj::ARENA> | 110 SortedLinkedList<ReservedMemoryRegion, compare_virtual_memory_base> |
113 _virtual_memory_regions; | 111 _virtual_memory_regions; |
114 size_t _count; | 112 size_t _count; |
115 | 113 |
116 public: | 114 public: |
117 VirtualMemoryAllocationWalker(Arena* a) : _count(0), _virtual_memory_regions(a) { | 115 VirtualMemoryAllocationWalker() : _count(0) { } |
118 } | |
119 | 116 |
120 bool do_allocation_site(const ReservedMemoryRegion* rgn) { | 117 bool do_allocation_site(const ReservedMemoryRegion* rgn) { |
121 if (rgn->size() >= MemBaseline::SIZE_THRESHOLD) { | 118 if (rgn->size() >= MemBaseline::SIZE_THRESHOLD) { |
122 if (_virtual_memory_regions.add(*rgn) != NULL) { | 119 if (_virtual_memory_regions.add(*rgn) != NULL) { |
123 _count ++; | 120 _count ++; |
134 } | 131 } |
135 }; | 132 }; |
136 | 133 |
137 | 134 |
138 bool MemBaseline::baseline_summary() { | 135 bool MemBaseline::baseline_summary() { |
139 assert(_malloc_memory_snapshot == NULL, "Malloc baseline not yet reset"); | 136 MallocMemorySummary::snapshot(&_malloc_memory_snapshot); |
140 assert(_virtual_memory_snapshot == NULL, "Virtual baseline not yet reset"); | 137 VirtualMemorySummary::snapshot(&_virtual_memory_snapshot); |
141 | |
142 _malloc_memory_snapshot = new (arena()) MallocMemorySnapshot(); | |
143 _virtual_memory_snapshot = new (arena()) VirtualMemorySnapshot(); | |
144 if (_malloc_memory_snapshot == NULL || _virtual_memory_snapshot == NULL) { | |
145 return false; | |
146 } | |
147 MallocMemorySummary::snapshot(_malloc_memory_snapshot); | |
148 VirtualMemorySummary::snapshot(_virtual_memory_snapshot); | |
149 return true; | 138 return true; |
150 } | 139 } |
151 | 140 |
152 bool MemBaseline::baseline_allocation_sites() { | 141 bool MemBaseline::baseline_allocation_sites() { |
153 assert(arena() != NULL, "Just check"); | |
154 // Malloc allocation sites | 142 // Malloc allocation sites |
155 MallocAllocationSiteWalker malloc_walker(arena()); | 143 MallocAllocationSiteWalker malloc_walker; |
156 if (!MallocSiteTable::walk_malloc_site(&malloc_walker)) { | 144 if (!MallocSiteTable::walk_malloc_site(&malloc_walker)) { |
157 return false; | 145 return false; |
158 } | 146 } |
159 | 147 |
160 _malloc_sites.set_head(malloc_walker.malloc_sites()->head()); | 148 _malloc_sites.move(malloc_walker.malloc_sites()); |
161 // The malloc sites are collected in size order | 149 // The malloc sites are collected in size order |
162 _malloc_sites_order = by_size; | 150 _malloc_sites_order = by_size; |
163 | 151 |
164 // Virtual memory allocation sites | 152 // Virtual memory allocation sites |
165 VirtualMemoryAllocationWalker virtual_memory_walker(arena()); | 153 VirtualMemoryAllocationWalker virtual_memory_walker; |
166 if (!VirtualMemoryTracker::walk_virtual_memory(&virtual_memory_walker)) { | 154 if (!VirtualMemoryTracker::walk_virtual_memory(&virtual_memory_walker)) { |
167 return false; | 155 return false; |
168 } | 156 } |
169 | 157 |
170 // Virtual memory allocations are collected in call stack order | 158 // Virtual memory allocations are collected in call stack order |
171 _virtual_memory_allocations.set_head(virtual_memory_walker.virtual_memory_allocations()->head()); | 159 _virtual_memory_allocations.move(virtual_memory_walker.virtual_memory_allocations()); |
172 | 160 |
173 if (!aggregate_virtual_memory_allocation_sites()) { | 161 if (!aggregate_virtual_memory_allocation_sites()) { |
174 return false; | 162 return false; |
175 } | 163 } |
176 // Virtual memory allocation sites are aggregrated in call stack order | 164 // Virtual memory allocation sites are aggregrated in call stack order |
178 | 166 |
179 return true; | 167 return true; |
180 } | 168 } |
181 | 169 |
182 bool MemBaseline::baseline(bool summaryOnly) { | 170 bool MemBaseline::baseline(bool summaryOnly) { |
183 if (arena() == NULL) { | |
184 _arena = new (std::nothrow, mtNMT) Arena(mtNMT); | |
185 if (arena() == NULL) return false; | |
186 } | |
187 | |
188 reset(); | 171 reset(); |
189 | 172 |
190 _class_count = InstanceKlass::number_of_instance_classes(); | 173 _class_count = InstanceKlass::number_of_instance_classes(); |
191 | 174 |
192 if (!baseline_summary()) { | 175 if (!baseline_summary()) { |
209 const VirtualMemoryAllocationSite& s2) { | 192 const VirtualMemoryAllocationSite& s2) { |
210 return s1.call_stack()->compare(*s2.call_stack()); | 193 return s1.call_stack()->compare(*s2.call_stack()); |
211 } | 194 } |
212 | 195 |
213 bool MemBaseline::aggregate_virtual_memory_allocation_sites() { | 196 bool MemBaseline::aggregate_virtual_memory_allocation_sites() { |
214 SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site, ResourceObj::ARENA> | 197 SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site> allocation_sites; |
215 allocation_sites(arena()); | |
216 | 198 |
217 VirtualMemoryAllocationIterator itr = virtual_memory_allocations(); | 199 VirtualMemoryAllocationIterator itr = virtual_memory_allocations(); |
218 const ReservedMemoryRegion* rgn; | 200 const ReservedMemoryRegion* rgn; |
219 VirtualMemoryAllocationSite* site; | 201 VirtualMemoryAllocationSite* site; |
220 while ((rgn = itr.next()) != NULL) { | 202 while ((rgn = itr.next()) != NULL) { |
228 } | 210 } |
229 site->reserve_memory(rgn->size()); | 211 site->reserve_memory(rgn->size()); |
230 site->commit_memory(rgn->committed_size()); | 212 site->commit_memory(rgn->committed_size()); |
231 } | 213 } |
232 | 214 |
233 _virtual_memory_sites.set_head(allocation_sites.head()); | 215 _virtual_memory_sites.move(&allocation_sites); |
234 return true; | 216 return true; |
235 } | 217 } |
236 | 218 |
237 MallocSiteIterator MemBaseline::malloc_sites(SortingOrder order) { | 219 MallocSiteIterator MemBaseline::malloc_sites(SortingOrder order) { |
238 assert(!_malloc_sites.is_empty(), "Detail baseline?"); | 220 assert(!_malloc_sites.is_empty(), "Not detail baseline"); |
239 switch(order) { | 221 switch(order) { |
240 case by_size: | 222 case by_size: |
241 malloc_sites_to_size_order(); | 223 malloc_sites_to_size_order(); |
242 break; | 224 break; |
243 case by_site: | 225 case by_site: |
249 } | 231 } |
250 return MallocSiteIterator(_malloc_sites.head()); | 232 return MallocSiteIterator(_malloc_sites.head()); |
251 } | 233 } |
252 | 234 |
253 VirtualMemorySiteIterator MemBaseline::virtual_memory_sites(SortingOrder order) { | 235 VirtualMemorySiteIterator MemBaseline::virtual_memory_sites(SortingOrder order) { |
254 assert(!_virtual_memory_sites.is_empty(), "Detail baseline?"); | 236 assert(!_virtual_memory_sites.is_empty(), "Not detail baseline"); |
255 switch(order) { | 237 switch(order) { |
256 case by_size: | 238 case by_size: |
257 virtual_memory_sites_to_size_order(); | 239 virtual_memory_sites_to_size_order(); |
258 break; | 240 break; |
259 case by_site: | 241 case by_site: |
268 | 250 |
269 | 251 |
270 // Sorting allocations sites in different orders | 252 // Sorting allocations sites in different orders |
271 void MemBaseline::malloc_sites_to_size_order() { | 253 void MemBaseline::malloc_sites_to_size_order() { |
272 if (_malloc_sites_order != by_size) { | 254 if (_malloc_sites_order != by_size) { |
273 SortedLinkedList<MallocSite, compare_malloc_size, ResourceObj::ARENA> | 255 SortedLinkedList<MallocSite, compare_malloc_size> tmp; |
274 tmp(arena()); | |
275 | 256 |
276 // Add malloc sites to sorted linked list to sort into size order | 257 // Add malloc sites to sorted linked list to sort into size order |
277 tmp.move(&_malloc_sites); | 258 tmp.move(&_malloc_sites); |
278 _malloc_sites.set_head(tmp.head()); | 259 _malloc_sites.set_head(tmp.head()); |
279 tmp.set_head(NULL); | 260 tmp.set_head(NULL); |
281 } | 262 } |
282 } | 263 } |
283 | 264 |
284 void MemBaseline::malloc_sites_to_allocation_site_order() { | 265 void MemBaseline::malloc_sites_to_allocation_site_order() { |
285 if (_malloc_sites_order != by_site) { | 266 if (_malloc_sites_order != by_site) { |
286 SortedLinkedList<MallocSite, compare_malloc_site, ResourceObj::ARENA> | 267 SortedLinkedList<MallocSite, compare_malloc_site> tmp; |
287 tmp(arena()); | |
288 // Add malloc sites to sorted linked list to sort into site (address) order | 268 // Add malloc sites to sorted linked list to sort into site (address) order |
289 tmp.move(&_malloc_sites); | 269 tmp.move(&_malloc_sites); |
290 _malloc_sites.set_head(tmp.head()); | 270 _malloc_sites.set_head(tmp.head()); |
291 tmp.set_head(NULL); | 271 tmp.set_head(NULL); |
292 _malloc_sites_order = by_site; | 272 _malloc_sites_order = by_site; |
293 } | 273 } |
294 } | 274 } |
295 | 275 |
296 void MemBaseline::virtual_memory_sites_to_size_order() { | 276 void MemBaseline::virtual_memory_sites_to_size_order() { |
297 if (_virtual_memory_sites_order != by_size) { | 277 if (_virtual_memory_sites_order != by_size) { |
298 SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size, ResourceObj::ARENA> | 278 SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size> tmp; |
299 tmp(arena()); | |
300 | 279 |
301 tmp.move(&_virtual_memory_sites); | 280 tmp.move(&_virtual_memory_sites); |
302 | 281 |
303 _virtual_memory_sites.set_head(tmp.head()); | 282 _virtual_memory_sites.set_head(tmp.head()); |
304 tmp.set_head(NULL); | 283 tmp.set_head(NULL); |
306 } | 285 } |
307 } | 286 } |
308 | 287 |
309 void MemBaseline::virtual_memory_sites_to_reservation_site_order() { | 288 void MemBaseline::virtual_memory_sites_to_reservation_site_order() { |
310 if (_virtual_memory_sites_order != by_size) { | 289 if (_virtual_memory_sites_order != by_size) { |
311 SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_site, ResourceObj::ARENA> | 290 SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_site> tmp; |
312 tmp(arena()); | 291 |
313 | 292 tmp.move(&_virtual_memory_sites); |
314 tmp.add(&_virtual_memory_sites); | |
315 | 293 |
316 _virtual_memory_sites.set_head(tmp.head()); | 294 _virtual_memory_sites.set_head(tmp.head()); |
317 tmp.set_head(NULL); | 295 tmp.set_head(NULL); |
318 | 296 |
319 _virtual_memory_sites_order = by_size; | 297 _virtual_memory_sites_order = by_size; |