Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp @ 12339:c319b188c7b2
8014078: G1: improve remembered set summary information by providing per region type information
Summary: Add memory consumption breakdown on a per region type in the G1 remembered set summary statistics. This simplifies remembered set memory consumption analysis.
Reviewed-by: brutisso
author | tschatzl |
---|---|
date | Thu, 26 Sep 2013 12:49:45 +0200 |
parents | 5888334c9c24 |
children | 7ec10139bf37 |
comparison
equal
deleted
inserted
replaced
12306:03f493ce3a71 | 12339:c319b188c7b2 |
---|---|
123 } | 123 } |
124 | 124 |
125 _sampling_thread_vtime = other->sampling_thread_vtime() - _sampling_thread_vtime; | 125 _sampling_thread_vtime = other->sampling_thread_vtime() - _sampling_thread_vtime; |
126 } | 126 } |
127 | 127 |
128 static double percent_of(size_t numerator, size_t denominator) { | |
129 if (denominator != 0) { | |
130 return (double)numerator / denominator * 100.0f; | |
131 } else { | |
132 return 0.0f; | |
133 } | |
134 } | |
135 | |
136 static size_t round_to_K(size_t value) { | |
137 return value / K; | |
138 } | |
139 | |
140 class RegionTypeCounter VALUE_OBJ_CLASS_SPEC { | |
141 private: | |
142 const char* _name; | |
143 | |
144 size_t _rs_mem_size; | |
145 size_t _cards_occupied; | |
146 size_t _amount; | |
147 | |
148 size_t _code_root_mem_size; | |
149 size_t _code_root_elems; | |
150 | |
151 double rs_mem_size_percent_of(size_t total) { | |
152 return percent_of(_rs_mem_size, total); | |
153 } | |
154 | |
155 double cards_occupied_percent_of(size_t total) { | |
156 return percent_of(_cards_occupied, total); | |
157 } | |
158 | |
159 double code_root_mem_size_percent_of(size_t total) { | |
160 return percent_of(_code_root_mem_size, total); | |
161 } | |
162 | |
163 double code_root_elems_percent_of(size_t total) { | |
164 return percent_of(_code_root_elems, total); | |
165 } | |
166 | |
167 size_t amount() const { return _amount; } | |
168 | |
169 public: | |
170 | |
171 RegionTypeCounter(const char* name) : _name(name), _rs_mem_size(0), _cards_occupied(0), | |
172 _amount(0), _code_root_mem_size(0), _code_root_elems(0) { } | |
173 | |
174 void add(size_t rs_mem_size, size_t cards_occupied, size_t code_root_mem_size, | |
175 size_t code_root_elems) { | |
176 _rs_mem_size += rs_mem_size; | |
177 _cards_occupied += cards_occupied; | |
178 _code_root_mem_size += code_root_mem_size; | |
179 _code_root_elems += code_root_elems; | |
180 _amount++; | |
181 } | |
182 | |
183 size_t rs_mem_size() const { return _rs_mem_size; } | |
184 size_t cards_occupied() const { return _cards_occupied; } | |
185 | |
186 size_t code_root_mem_size() const { return _code_root_mem_size; } | |
187 size_t code_root_elems() const { return _code_root_elems; } | |
188 | |
189 void print_rs_mem_info_on(outputStream * out, size_t total) { | |
190 out->print_cr(" %8dK (%5.1f%%) by %zd %s regions", round_to_K(rs_mem_size()), rs_mem_size_percent_of(total), amount(), _name); | |
191 } | |
192 | |
193 void print_cards_occupied_info_on(outputStream * out, size_t total) { | |
194 out->print_cr(" %8d (%5.1f%%) entries by %zd %s regions", cards_occupied(), cards_occupied_percent_of(total), amount(), _name); | |
195 } | |
196 | |
197 void print_code_root_mem_info_on(outputStream * out, size_t total) { | |
198 out->print_cr(" %8dK (%5.1f%%) by %zd %s regions", round_to_K(code_root_mem_size()), code_root_mem_size_percent_of(total), amount(), _name); | |
199 } | |
200 | |
201 void print_code_root_elems_info_on(outputStream * out, size_t total) { | |
202 out->print_cr(" %8d (%5.1f%%) elements by %zd %s regions", code_root_elems(), code_root_elems_percent_of(total), amount(), _name); | |
203 } | |
204 }; | |
205 | |
206 | |
128 class HRRSStatsIter: public HeapRegionClosure { | 207 class HRRSStatsIter: public HeapRegionClosure { |
129 size_t _occupied; | 208 private: |
130 | 209 RegionTypeCounter _young; |
131 size_t _total_rs_mem_sz; | 210 RegionTypeCounter _humonguous; |
211 RegionTypeCounter _free; | |
212 RegionTypeCounter _old; | |
213 RegionTypeCounter _all; | |
214 | |
132 size_t _max_rs_mem_sz; | 215 size_t _max_rs_mem_sz; |
133 HeapRegion* _max_rs_mem_sz_region; | 216 HeapRegion* _max_rs_mem_sz_region; |
134 | 217 |
135 size_t _total_code_root_mem_sz; | 218 size_t total_rs_mem_sz() const { return _all.rs_mem_size(); } |
219 size_t total_cards_occupied() const { return _all.cards_occupied(); } | |
220 | |
221 size_t max_rs_mem_sz() const { return _max_rs_mem_sz; } | |
222 HeapRegion* max_rs_mem_sz_region() const { return _max_rs_mem_sz_region; } | |
223 | |
136 size_t _max_code_root_mem_sz; | 224 size_t _max_code_root_mem_sz; |
137 HeapRegion* _max_code_root_mem_sz_region; | 225 HeapRegion* _max_code_root_mem_sz_region; |
226 | |
227 size_t total_code_root_mem_sz() const { return _all.code_root_mem_size(); } | |
228 size_t total_code_root_elems() const { return _all.code_root_elems(); } | |
229 | |
230 size_t max_code_root_mem_sz() const { return _max_code_root_mem_sz; } | |
231 HeapRegion* max_code_root_mem_sz_region() const { return _max_code_root_mem_sz_region; } | |
232 | |
138 public: | 233 public: |
139 HRRSStatsIter() : | 234 HRRSStatsIter() : _all("All"), _young("Young"), _humonguous("Humonguous"), |
140 _occupied(0), | 235 _free("Free"), _old("Old"), _max_code_root_mem_sz_region(NULL), _max_rs_mem_sz_region(NULL), |
141 _total_rs_mem_sz(0), | 236 _max_rs_mem_sz(0), _max_code_root_mem_sz(0) |
142 _max_rs_mem_sz(0), | |
143 _max_rs_mem_sz_region(NULL), | |
144 _total_code_root_mem_sz(0), | |
145 _max_code_root_mem_sz(0), | |
146 _max_code_root_mem_sz_region(NULL) | |
147 {} | 237 {} |
148 | 238 |
149 bool doHeapRegion(HeapRegion* r) { | 239 bool doHeapRegion(HeapRegion* r) { |
150 HeapRegionRemSet* hrrs = r->rem_set(); | 240 HeapRegionRemSet* hrrs = r->rem_set(); |
151 | 241 |
154 size_t rs_mem_sz = hrrs->mem_size(); | 244 size_t rs_mem_sz = hrrs->mem_size(); |
155 if (rs_mem_sz > _max_rs_mem_sz) { | 245 if (rs_mem_sz > _max_rs_mem_sz) { |
156 _max_rs_mem_sz = rs_mem_sz; | 246 _max_rs_mem_sz = rs_mem_sz; |
157 _max_rs_mem_sz_region = r; | 247 _max_rs_mem_sz_region = r; |
158 } | 248 } |
159 _total_rs_mem_sz += rs_mem_sz; | 249 size_t occupied_cards = hrrs->occupied(); |
160 | |
161 size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size(); | 250 size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size(); |
162 if (code_root_mem_sz > _max_code_root_mem_sz) { | 251 if (code_root_mem_sz > max_code_root_mem_sz()) { |
163 _max_code_root_mem_sz = code_root_mem_sz; | |
164 _max_code_root_mem_sz_region = r; | 252 _max_code_root_mem_sz_region = r; |
165 } | 253 } |
166 _total_code_root_mem_sz += code_root_mem_sz; | 254 size_t code_root_elems = hrrs->strong_code_roots_list_length(); |
167 | 255 |
168 size_t occ = hrrs->occupied(); | 256 RegionTypeCounter* current = NULL; |
169 _occupied += occ; | 257 if (r->is_young()) { |
258 current = &_young; | |
259 } else if (r->isHumongous()) { | |
260 current = &_humonguous; | |
261 } else if (r->is_empty()) { | |
262 current = &_free; | |
263 } else { | |
264 current = &_old; | |
265 } | |
266 current->add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems); | |
267 _all.add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems); | |
268 | |
170 return false; | 269 return false; |
171 } | 270 } |
172 size_t total_rs_mem_sz() { return _total_rs_mem_sz; } | 271 |
173 size_t max_rs_mem_sz() { return _max_rs_mem_sz; } | 272 void print_summary_on(outputStream* out) { |
174 HeapRegion* max_rs_mem_sz_region() { return _max_rs_mem_sz_region; } | 273 RegionTypeCounter* counters[] = { &_young, &_humonguous, &_free, &_old, NULL }; |
175 size_t total_code_root_mem_sz() { return _total_code_root_mem_sz; } | 274 |
176 size_t max_code_root_mem_sz() { return _max_code_root_mem_sz; } | 275 out->print_cr("\n Current rem set statistics"); |
177 HeapRegion* max_code_root_mem_sz_region() { return _max_code_root_mem_sz_region; } | 276 out->print_cr(" Total per region rem sets sizes = "SIZE_FORMAT"K." |
178 size_t occupied() { return _occupied; } | 277 " Max = "SIZE_FORMAT"K.", |
278 round_to_K(total_rs_mem_sz()), round_to_K(max_rs_mem_sz())); | |
279 for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { | |
280 (*current)->print_rs_mem_info_on(out, total_rs_mem_sz()); | |
281 } | |
282 | |
283 out->print_cr(" Static structures = "SIZE_FORMAT"K," | |
284 " free_lists = "SIZE_FORMAT"K.", | |
285 round_to_K(HeapRegionRemSet::static_mem_size()), | |
286 round_to_K(HeapRegionRemSet::fl_mem_size())); | |
287 | |
288 out->print_cr(" "SIZE_FORMAT" occupied cards represented.", | |
289 total_cards_occupied()); | |
290 for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { | |
291 (*current)->print_cards_occupied_info_on(out, total_cards_occupied()); | |
292 } | |
293 | |
294 // Largest sized rem set region statistics | |
295 HeapRegionRemSet* rem_set = max_rs_mem_sz_region()->rem_set(); | |
296 out->print_cr(" Region with largest rem set = "HR_FORMAT", " | |
297 "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.", | |
298 HR_FORMAT_PARAMS(max_rs_mem_sz_region()), | |
299 round_to_K(rem_set->mem_size()), | |
300 round_to_K(rem_set->occupied())); | |
301 | |
302 // Strong code root statistics | |
303 HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region()->rem_set(); | |
304 out->print_cr(" Total heap region code root sets sizes = "SIZE_FORMAT"K." | |
305 " Max = "SIZE_FORMAT"K.", | |
306 round_to_K(total_code_root_mem_sz()), | |
307 round_to_K(max_code_root_rem_set->strong_code_roots_mem_size())); | |
308 for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { | |
309 (*current)->print_code_root_mem_info_on(out, total_code_root_mem_sz()); | |
310 } | |
311 | |
312 out->print_cr(" "SIZE_FORMAT" code roots represented.", | |
313 total_code_root_elems()); | |
314 for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { | |
315 (*current)->print_code_root_elems_info_on(out, total_code_root_elems()); | |
316 } | |
317 | |
318 out->print_cr(" Region with largest amount of code roots = "HR_FORMAT", " | |
319 "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".", | |
320 HR_FORMAT_PARAMS(max_code_root_mem_sz_region()), | |
321 round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()), | |
322 round_to_K(max_code_root_rem_set->strong_code_roots_list_length())); | |
323 } | |
179 }; | 324 }; |
180 | 325 |
181 double calc_percentage(size_t numerator, size_t denominator) { | |
182 if (denominator != 0) { | |
183 return (double)numerator / denominator * 100.0; | |
184 } else { | |
185 return 0.0f; | |
186 } | |
187 } | |
188 | |
189 void G1RemSetSummary::print_on(outputStream* out) { | 326 void G1RemSetSummary::print_on(outputStream* out) { |
190 out->print_cr("\n Concurrent RS processed "SIZE_FORMAT" cards", | 327 out->print_cr("\n Recent concurrent refinement statistics"); |
328 out->print_cr(" Processed "SIZE_FORMAT" cards", | |
191 num_concurrent_refined_cards()); | 329 num_concurrent_refined_cards()); |
192 out->print_cr(" Of %d completed buffers:", num_processed_buf_total()); | 330 out->print_cr(" Of %d completed buffers:", num_processed_buf_total()); |
193 out->print_cr(" %8d (%5.1f%%) by concurrent RS threads.", | 331 out->print_cr(" %8d (%5.1f%%) by concurrent RS threads.", |
194 num_processed_buf_total(), | 332 num_processed_buf_total(), |
195 calc_percentage(num_processed_buf_rs_threads(), num_processed_buf_total())); | 333 percent_of(num_processed_buf_rs_threads(), num_processed_buf_total())); |
196 out->print_cr(" %8d (%5.1f%%) by mutator threads.", | 334 out->print_cr(" %8d (%5.1f%%) by mutator threads.", |
197 num_processed_buf_mutator(), | 335 num_processed_buf_mutator(), |
198 calc_percentage(num_processed_buf_mutator(), num_processed_buf_total())); | 336 percent_of(num_processed_buf_mutator(), num_processed_buf_total())); |
337 out->print_cr(" Did %d coarsenings.", num_coarsenings()); | |
199 out->print_cr(" Concurrent RS threads times (s)"); | 338 out->print_cr(" Concurrent RS threads times (s)"); |
200 out->print(" "); | 339 out->print(" "); |
201 for (uint i = 0; i < _num_vtimes; i++) { | 340 for (uint i = 0; i < _num_vtimes; i++) { |
202 out->print(" %5.2f", rs_thread_vtime(i)); | 341 out->print(" %5.2f", rs_thread_vtime(i)); |
203 } | 342 } |
205 out->print_cr(" Concurrent sampling threads times (s)"); | 344 out->print_cr(" Concurrent sampling threads times (s)"); |
206 out->print_cr(" %5.2f", sampling_thread_vtime()); | 345 out->print_cr(" %5.2f", sampling_thread_vtime()); |
207 | 346 |
208 HRRSStatsIter blk; | 347 HRRSStatsIter blk; |
209 G1CollectedHeap::heap()->heap_region_iterate(&blk); | 348 G1CollectedHeap::heap()->heap_region_iterate(&blk); |
210 // RemSet stats | 349 blk.print_summary_on(out); |
211 out->print_cr(" Total heap region rem set sizes = "SIZE_FORMAT"K." | 350 } |
212 " Max = "SIZE_FORMAT"K.", | |
213 blk.total_rs_mem_sz()/K, blk.max_rs_mem_sz()/K); | |
214 out->print_cr(" Static structures = "SIZE_FORMAT"K," | |
215 " free_lists = "SIZE_FORMAT"K.", | |
216 HeapRegionRemSet::static_mem_size() / K, | |
217 HeapRegionRemSet::fl_mem_size() / K); | |
218 out->print_cr(" "SIZE_FORMAT" occupied cards represented.", | |
219 blk.occupied()); | |
220 HeapRegion* max_rs_mem_sz_region = blk.max_rs_mem_sz_region(); | |
221 HeapRegionRemSet* max_rs_rem_set = max_rs_mem_sz_region->rem_set(); | |
222 out->print_cr(" Max size region = "HR_FORMAT", " | |
223 "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.", | |
224 HR_FORMAT_PARAMS(max_rs_mem_sz_region), | |
225 (max_rs_rem_set->mem_size() + K - 1)/K, | |
226 (max_rs_rem_set->occupied() + K - 1)/K); | |
227 out->print_cr(" Did %d coarsenings.", num_coarsenings()); | |
228 // Strong code root stats | |
229 out->print_cr(" Total heap region code-root set sizes = "SIZE_FORMAT"K." | |
230 " Max = "SIZE_FORMAT"K.", | |
231 blk.total_code_root_mem_sz()/K, blk.max_code_root_mem_sz()/K); | |
232 HeapRegion* max_code_root_mem_sz_region = blk.max_code_root_mem_sz_region(); | |
233 HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region->rem_set(); | |
234 out->print_cr(" Max size region = "HR_FORMAT", " | |
235 "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".", | |
236 HR_FORMAT_PARAMS(max_code_root_mem_sz_region), | |
237 (max_code_root_rem_set->strong_code_roots_mem_size() + K - 1)/K, | |
238 (max_code_root_rem_set->strong_code_roots_list_length())); | |
239 } |