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 }