src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp

Print this page
rev 6327 : 8019342: G1: High "Other" time most likely due to card redirtying
Summary: Parallelize card redirtying to decrease the time it takes.
Reviewed-by: brutisso


 156 }
 157 
 158 #endif
 159 
 160 G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
 161   _max_gc_threads(max_gc_threads),
 162   _last_gc_worker_start_times_ms(_max_gc_threads, "%.1lf", false),
 163   _last_ext_root_scan_times_ms(_max_gc_threads, "%.1lf"),
 164   _last_satb_filtering_times_ms(_max_gc_threads, "%.1lf"),
 165   _last_update_rs_times_ms(_max_gc_threads, "%.1lf"),
 166   _last_update_rs_processed_buffers(_max_gc_threads, "%d"),
 167   _last_scan_rs_times_ms(_max_gc_threads, "%.1lf"),
 168   _last_strong_code_root_scan_times_ms(_max_gc_threads, "%.1lf"),
 169   _last_strong_code_root_mark_times_ms(_max_gc_threads, "%.1lf"),
 170   _last_obj_copy_times_ms(_max_gc_threads, "%.1lf"),
 171   _last_termination_times_ms(_max_gc_threads, "%.1lf"),
 172   _last_termination_attempts(_max_gc_threads, SIZE_FORMAT),
 173   _last_gc_worker_end_times_ms(_max_gc_threads, "%.1lf", false),
 174   _last_gc_worker_times_ms(_max_gc_threads, "%.1lf"),
 175   _last_gc_worker_other_times_ms(_max_gc_threads, "%.1lf"),


 176   _cur_string_dedup_queue_fixup_worker_times_ms(_max_gc_threads, "%.1lf"),
 177   _cur_string_dedup_table_fixup_worker_times_ms(_max_gc_threads, "%.1lf")
 178 {
 179   assert(max_gc_threads > 0, "Must have some GC threads");
 180 }
 181 
 182 void G1GCPhaseTimes::note_gc_start(uint active_gc_threads) {
 183   assert(active_gc_threads > 0, "The number of threads must be > 0");
 184   assert(active_gc_threads <= _max_gc_threads, "The number of active threads must be <= the max nubmer of threads");
 185   _active_gc_threads = active_gc_threads;
 186 
 187   _last_gc_worker_start_times_ms.reset();
 188   _last_ext_root_scan_times_ms.reset();
 189   _last_satb_filtering_times_ms.reset();
 190   _last_update_rs_times_ms.reset();
 191   _last_update_rs_processed_buffers.reset();
 192   _last_scan_rs_times_ms.reset();
 193   _last_strong_code_root_scan_times_ms.reset();
 194   _last_strong_code_root_mark_times_ms.reset();
 195   _last_obj_copy_times_ms.reset();
 196   _last_termination_times_ms.reset();
 197   _last_termination_attempts.reset();
 198   _last_gc_worker_end_times_ms.reset();
 199   _last_gc_worker_times_ms.reset();
 200   _last_gc_worker_other_times_ms.reset();




 201 }
 202 
 203 void G1GCPhaseTimes::note_gc_end() {
 204   _last_gc_worker_start_times_ms.verify();
 205   _last_ext_root_scan_times_ms.verify();
 206   _last_satb_filtering_times_ms.verify();
 207   _last_update_rs_times_ms.verify();
 208   _last_update_rs_processed_buffers.verify();
 209   _last_scan_rs_times_ms.verify();
 210   _last_strong_code_root_scan_times_ms.verify();
 211   _last_strong_code_root_mark_times_ms.verify();
 212   _last_obj_copy_times_ms.verify();
 213   _last_termination_times_ms.verify();
 214   _last_termination_attempts.verify();
 215   _last_gc_worker_end_times_ms.verify();
 216 
 217   for (uint i = 0; i < _active_gc_threads; i++) {
 218     double worker_time = _last_gc_worker_end_times_ms.get(i) - _last_gc_worker_start_times_ms.get(i);
 219     _last_gc_worker_times_ms.set(i, worker_time);
 220 
 221     double worker_known_time = _last_ext_root_scan_times_ms.get(i) +
 222                                _last_satb_filtering_times_ms.get(i) +
 223                                _last_update_rs_times_ms.get(i) +
 224                                _last_scan_rs_times_ms.get(i) +
 225                                _last_strong_code_root_scan_times_ms.get(i) +
 226                                _last_strong_code_root_mark_times_ms.get(i) +
 227                                _last_obj_copy_times_ms.get(i) +
 228                                _last_termination_times_ms.get(i);
 229 
 230     double worker_other_time = worker_time - worker_known_time;
 231     _last_gc_worker_other_times_ms.set(i, worker_other_time);
 232   }
 233 
 234   _last_gc_worker_times_ms.verify();
 235   _last_gc_worker_other_times_ms.verify();



 236 }
 237 
 238 void G1GCPhaseTimes::note_string_dedup_fixup_start() {
 239   _cur_string_dedup_queue_fixup_worker_times_ms.reset();
 240   _cur_string_dedup_table_fixup_worker_times_ms.reset();
 241 }
 242 
 243 void G1GCPhaseTimes::note_string_dedup_fixup_end() {
 244   _cur_string_dedup_queue_fixup_worker_times_ms.verify();
 245   _cur_string_dedup_table_fixup_worker_times_ms.verify();
 246 }
 247 
 248 void G1GCPhaseTimes::print_stats(int level, const char* str, double value) {
 249   LineBuffer(level).append_and_print_cr("[%s: %.1lf ms]", str, value);
 250 }
 251 
 252 void G1GCPhaseTimes::print_stats(int level, const char* str, double value, uint workers) {
 253   LineBuffer(level).append_and_print_cr("[%s: %.1lf ms, GC Workers: " UINT32_FORMAT "]", str, value, workers);
 254 }
 255 


 335   if (_cur_verify_before_time_ms > 0.0) {
 336     print_stats(2, "Verify Before", _cur_verify_before_time_ms);
 337   }
 338   if (G1CollectedHeap::heap()->evacuation_failed()) {
 339     double evac_fail_handling = _cur_evac_fail_recalc_used + _cur_evac_fail_remove_self_forwards +
 340       _cur_evac_fail_restore_remsets;
 341     print_stats(2, "Evacuation Failure", evac_fail_handling);
 342     if (G1Log::finest()) {
 343       print_stats(3, "Recalculate Used", _cur_evac_fail_recalc_used);
 344       print_stats(3, "Remove Self Forwards", _cur_evac_fail_remove_self_forwards);
 345       print_stats(3, "Restore RemSet", _cur_evac_fail_restore_remsets);
 346     }
 347   }
 348   print_stats(2, "Choose CSet",
 349     (_recorded_young_cset_choice_time_ms +
 350     _recorded_non_young_cset_choice_time_ms));
 351   print_stats(2, "Ref Proc", _cur_ref_proc_time_ms);
 352   print_stats(2, "Ref Enq", _cur_ref_enq_time_ms);
 353   if (G1DeferredRSUpdate) {
 354     print_stats(2, "Redirty Cards", _recorded_redirty_logged_cards_time_ms);




 355   }
 356   print_stats(2, "Free CSet",
 357     (_recorded_young_free_cset_time_ms +
 358     _recorded_non_young_free_cset_time_ms));
 359   if (G1Log::finest()) {
 360     print_stats(3, "Young Free CSet", _recorded_young_free_cset_time_ms);
 361     print_stats(3, "Non-Young Free CSet", _recorded_non_young_free_cset_time_ms);
 362   }
 363   if (_cur_verify_after_time_ms > 0.0) {
 364     print_stats(2, "Verify After", _cur_verify_after_time_ms);
 365   }
 366 }


 156 }
 157 
 158 #endif
 159 
 160 G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
 161   _max_gc_threads(max_gc_threads),
 162   _last_gc_worker_start_times_ms(_max_gc_threads, "%.1lf", false),
 163   _last_ext_root_scan_times_ms(_max_gc_threads, "%.1lf"),
 164   _last_satb_filtering_times_ms(_max_gc_threads, "%.1lf"),
 165   _last_update_rs_times_ms(_max_gc_threads, "%.1lf"),
 166   _last_update_rs_processed_buffers(_max_gc_threads, "%d"),
 167   _last_scan_rs_times_ms(_max_gc_threads, "%.1lf"),
 168   _last_strong_code_root_scan_times_ms(_max_gc_threads, "%.1lf"),
 169   _last_strong_code_root_mark_times_ms(_max_gc_threads, "%.1lf"),
 170   _last_obj_copy_times_ms(_max_gc_threads, "%.1lf"),
 171   _last_termination_times_ms(_max_gc_threads, "%.1lf"),
 172   _last_termination_attempts(_max_gc_threads, SIZE_FORMAT),
 173   _last_gc_worker_end_times_ms(_max_gc_threads, "%.1lf", false),
 174   _last_gc_worker_times_ms(_max_gc_threads, "%.1lf"),
 175   _last_gc_worker_other_times_ms(_max_gc_threads, "%.1lf"),
 176   _last_redirty_logged_cards_time_ms(_max_gc_threads, "%.1lf"),
 177   _last_redirty_logged_cards_processed_cards(_max_gc_threads, SIZE_FORMAT),
 178   _cur_string_dedup_queue_fixup_worker_times_ms(_max_gc_threads, "%.1lf"),
 179   _cur_string_dedup_table_fixup_worker_times_ms(_max_gc_threads, "%.1lf")
 180 {
 181   assert(max_gc_threads > 0, "Must have some GC threads");
 182 }
 183 
 184 void G1GCPhaseTimes::note_gc_start(uint active_gc_threads) {
 185   assert(active_gc_threads > 0, "The number of threads must be > 0");
 186   assert(active_gc_threads <= _max_gc_threads, "The number of active threads must be <= the max nubmer of threads");
 187   _active_gc_threads = active_gc_threads;
 188 
 189   _last_gc_worker_start_times_ms.reset();
 190   _last_ext_root_scan_times_ms.reset();
 191   _last_satb_filtering_times_ms.reset();
 192   _last_update_rs_times_ms.reset();
 193   _last_update_rs_processed_buffers.reset();
 194   _last_scan_rs_times_ms.reset();
 195   _last_strong_code_root_scan_times_ms.reset();
 196   _last_strong_code_root_mark_times_ms.reset();
 197   _last_obj_copy_times_ms.reset();
 198   _last_termination_times_ms.reset();
 199   _last_termination_attempts.reset();
 200   _last_gc_worker_end_times_ms.reset();
 201   _last_gc_worker_times_ms.reset();
 202   _last_gc_worker_other_times_ms.reset();
 203 
 204   _last_redirty_logged_cards_time_ms.reset();
 205   _last_redirty_logged_cards_processed_cards.reset();
 206 
 207 }
 208 
 209 void G1GCPhaseTimes::note_gc_end() {
 210   _last_gc_worker_start_times_ms.verify();
 211   _last_ext_root_scan_times_ms.verify();
 212   _last_satb_filtering_times_ms.verify();
 213   _last_update_rs_times_ms.verify();
 214   _last_update_rs_processed_buffers.verify();
 215   _last_scan_rs_times_ms.verify();
 216   _last_strong_code_root_scan_times_ms.verify();
 217   _last_strong_code_root_mark_times_ms.verify();
 218   _last_obj_copy_times_ms.verify();
 219   _last_termination_times_ms.verify();
 220   _last_termination_attempts.verify();
 221   _last_gc_worker_end_times_ms.verify();
 222 
 223   for (uint i = 0; i < _active_gc_threads; i++) {
 224     double worker_time = _last_gc_worker_end_times_ms.get(i) - _last_gc_worker_start_times_ms.get(i);
 225     _last_gc_worker_times_ms.set(i, worker_time);
 226 
 227     double worker_known_time = _last_ext_root_scan_times_ms.get(i) +
 228                                _last_satb_filtering_times_ms.get(i) +
 229                                _last_update_rs_times_ms.get(i) +
 230                                _last_scan_rs_times_ms.get(i) +
 231                                _last_strong_code_root_scan_times_ms.get(i) +
 232                                _last_strong_code_root_mark_times_ms.get(i) +
 233                                _last_obj_copy_times_ms.get(i) +
 234                                _last_termination_times_ms.get(i);
 235 
 236     double worker_other_time = worker_time - worker_known_time;
 237     _last_gc_worker_other_times_ms.set(i, worker_other_time);
 238   }
 239 
 240   _last_gc_worker_times_ms.verify();
 241   _last_gc_worker_other_times_ms.verify();
 242 
 243   _last_redirty_logged_cards_time_ms.verify();
 244   _last_redirty_logged_cards_processed_cards.verify();
 245 }
 246 
 247 void G1GCPhaseTimes::note_string_dedup_fixup_start() {
 248   _cur_string_dedup_queue_fixup_worker_times_ms.reset();
 249   _cur_string_dedup_table_fixup_worker_times_ms.reset();
 250 }
 251 
 252 void G1GCPhaseTimes::note_string_dedup_fixup_end() {
 253   _cur_string_dedup_queue_fixup_worker_times_ms.verify();
 254   _cur_string_dedup_table_fixup_worker_times_ms.verify();
 255 }
 256 
 257 void G1GCPhaseTimes::print_stats(int level, const char* str, double value) {
 258   LineBuffer(level).append_and_print_cr("[%s: %.1lf ms]", str, value);
 259 }
 260 
 261 void G1GCPhaseTimes::print_stats(int level, const char* str, double value, uint workers) {
 262   LineBuffer(level).append_and_print_cr("[%s: %.1lf ms, GC Workers: " UINT32_FORMAT "]", str, value, workers);
 263 }
 264 


 344   if (_cur_verify_before_time_ms > 0.0) {
 345     print_stats(2, "Verify Before", _cur_verify_before_time_ms);
 346   }
 347   if (G1CollectedHeap::heap()->evacuation_failed()) {
 348     double evac_fail_handling = _cur_evac_fail_recalc_used + _cur_evac_fail_remove_self_forwards +
 349       _cur_evac_fail_restore_remsets;
 350     print_stats(2, "Evacuation Failure", evac_fail_handling);
 351     if (G1Log::finest()) {
 352       print_stats(3, "Recalculate Used", _cur_evac_fail_recalc_used);
 353       print_stats(3, "Remove Self Forwards", _cur_evac_fail_remove_self_forwards);
 354       print_stats(3, "Restore RemSet", _cur_evac_fail_restore_remsets);
 355     }
 356   }
 357   print_stats(2, "Choose CSet",
 358     (_recorded_young_cset_choice_time_ms +
 359     _recorded_non_young_cset_choice_time_ms));
 360   print_stats(2, "Ref Proc", _cur_ref_proc_time_ms);
 361   print_stats(2, "Ref Enq", _cur_ref_enq_time_ms);
 362   if (G1DeferredRSUpdate) {
 363     print_stats(2, "Redirty Cards", _recorded_redirty_logged_cards_time_ms);
 364     if (G1Log::finest()) {
 365       _last_redirty_logged_cards_time_ms.print(3, "Parallel Redirty");
 366       _last_redirty_logged_cards_processed_cards.print(3, "Redirtied Cards");
 367     }
 368   }
 369   print_stats(2, "Free CSet",
 370     (_recorded_young_free_cset_time_ms +
 371     _recorded_non_young_free_cset_time_ms));
 372   if (G1Log::finest()) {
 373     print_stats(3, "Young Free CSet", _recorded_young_free_cset_time_ms);
 374     print_stats(3, "Non-Young Free CSet", _recorded_non_young_free_cset_time_ms);
 375   }
 376   if (_cur_verify_after_time_ms > 0.0) {
 377     print_stats(2, "Verify After", _cur_verify_after_time_ms);
 378   }
 379 }