@@ -211,138 +211,12 @@ void MemTracker::report(bool summary_only, outputStream* output, size_t scale) {
211
211
}
212
212
}
213
213
214
- // This is a walker to gather malloc site hashtable statistics,
215
- // the result is used for tuning.
216
- class StatisticsWalker : public MallocSiteWalker {
217
- private:
218
- enum Threshold {
219
- // aggregates statistics over this threshold into one
220
- // line item.
221
- report_threshold = 20
222
- };
223
-
224
- private:
225
- // Number of allocation sites that have all memory freed
226
- int _empty_entries;
227
- // Total number of allocation sites, include empty sites
228
- int _total_entries;
229
- // Number of captured call stack distribution
230
- int _stack_depth_distribution[NMT_TrackingStackDepth];
231
- // Hash distribution
232
- int _hash_distribution[report_threshold];
233
- // Number of hash buckets that have entries over the threshold
234
- int _bucket_over_threshold;
235
-
236
- // The hash bucket that walker is currently walking
237
- int _current_hash_bucket;
238
- // The length of current hash bucket
239
- int _current_bucket_length;
240
- // Number of hash buckets that are not empty
241
- int _used_buckets;
242
- // Longest hash bucket length
243
- int _longest_bucket_length;
244
-
245
- public:
246
- StatisticsWalker () : _empty_entries(0 ), _total_entries(0 ) {
247
- int index = 0 ;
248
- for (index = 0 ; index < NMT_TrackingStackDepth; index ++) {
249
- _stack_depth_distribution[index ] = 0 ;
250
- }
251
- for (index = 0 ; index < report_threshold; index ++) {
252
- _hash_distribution[index ] = 0 ;
253
- }
254
- _bucket_over_threshold = 0 ;
255
- _longest_bucket_length = 0 ;
256
- _current_hash_bucket = -1 ;
257
- _current_bucket_length = 0 ;
258
- _used_buckets = 0 ;
259
- }
260
-
261
- virtual bool do_malloc_site (const MallocSite* e) {
262
- if (e->size () == 0 ) _empty_entries ++;
263
- _total_entries ++;
264
-
265
- // stack depth distrubution
266
- int frames = e->call_stack ()->frames ();
267
- _stack_depth_distribution[frames - 1 ] ++;
268
-
269
- // hash distribution
270
- int hash_bucket = ((unsigned )e->hash ()) % MallocSiteTable::hash_buckets ();
271
- if (_current_hash_bucket == -1 ) {
272
- _current_hash_bucket = hash_bucket;
273
- _current_bucket_length = 1 ;
274
- } else if (_current_hash_bucket == hash_bucket) {
275
- _current_bucket_length ++;
276
- } else {
277
- record_bucket_length (_current_bucket_length);
278
- _current_hash_bucket = hash_bucket;
279
- _current_bucket_length = 1 ;
280
- }
281
- return true ;
282
- }
283
-
284
- // walk completed
285
- void completed () {
286
- record_bucket_length (_current_bucket_length);
287
- }
288
-
289
- void report_statistics (outputStream* out) {
290
- int index ;
291
- out->print_cr (" Malloc allocation site table:" );
292
- out->print_cr (" \t Total entries: %d" , _total_entries);
293
- out->print_cr (" \t Empty entries: %d (%2.2f%%)" , _empty_entries, ((float )_empty_entries * 100 ) / _total_entries);
294
- out->print_cr (" " );
295
- out->print_cr (" Hash distribution:" );
296
- if (_used_buckets < MallocSiteTable::hash_buckets ()) {
297
- out->print_cr (" empty bucket: %d" , (MallocSiteTable::hash_buckets () - _used_buckets));
298
- }
299
- for (index = 0 ; index < report_threshold; index ++) {
300
- if (_hash_distribution[index ] != 0 ) {
301
- if (index == 0 ) {
302
- out->print_cr (" %d entry: %d" , 1 , _hash_distribution[0 ]);
303
- } else if (index < 9 ) { // single digit
304
- out->print_cr (" %d entries: %d" , (index + 1 ), _hash_distribution[index ]);
305
- } else {
306
- out->print_cr (" %d entries: %d" , (index + 1 ), _hash_distribution[index ]);
307
- }
308
- }
309
- }
310
- if (_bucket_over_threshold > 0 ) {
311
- out->print_cr (" >%d entries: %d" , report_threshold, _bucket_over_threshold);
312
- }
313
- out->print_cr (" most entries: %d" , _longest_bucket_length);
314
- out->print_cr (" " );
315
- out->print_cr (" Call stack depth distribution:" );
316
- for (index = 0 ; index < NMT_TrackingStackDepth; index ++) {
317
- if (_stack_depth_distribution[index ] > 0 ) {
318
- out->print_cr (" \t %d: %d" , index + 1 , _stack_depth_distribution[index ]);
319
- }
320
- }
321
- }
322
-
323
- private:
324
- void record_bucket_length (int length) {
325
- _used_buckets ++;
326
- if (length <= report_threshold) {
327
- _hash_distribution[length - 1 ] ++;
328
- } else {
329
- _bucket_over_threshold ++;
330
- }
331
- _longest_bucket_length = MAX2 (_longest_bucket_length, length);
332
- }
333
- };
334
-
335
-
336
214
void MemTracker::tuning_statistics (outputStream* out) {
337
215
// NMT statistics
338
- StatisticsWalker walker;
339
- MallocSiteTable::walk_malloc_site (&walker);
340
- walker.completed ();
341
-
342
216
out->print_cr (" Native Memory Tracking Statistics:" );
343
217
out->print_cr (" Malloc allocation site table size: %d" , MallocSiteTable::hash_buckets ());
344
218
out->print_cr (" Tracking stack depth: %d" , NMT_TrackingStackDepth);
345
219
NOT_PRODUCT (out->print_cr (" Peak concurrent access: %d" , MallocSiteTable::access_peak_count ());)
346
- out->print_cr ( " " );
347
- walker. report_statistics (out);
220
+ out->cr ( );
221
+ MallocSiteTable::print_tuning_statistics (out);
348
222
}
0 commit comments