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;