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

Print this page
rev 4467 : 8010780: G1: Eden occupancy/capacity output wrong after a full GC
Summary: Move the calculation and recording of eden capacity to the start of a GC and print a detailed heap transition for full GCs.
Reviewed-by: tschatzl, jmasa
   1 /*
   2  * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 389   }
 390 
 391   assert(_min_desired_young_length <= _max_desired_young_length, "Invalid min/max young gen size values");
 392 }
 393 
 394 void G1CollectorPolicy::init() {
 395   // Set aside an initial future to_space.
 396   _g1 = G1CollectedHeap::heap();
 397 
 398   assert(Heap_lock->owned_by_self(), "Locking discipline.");
 399 
 400   initialize_gc_policy_counters();
 401 
 402   if (adaptive_young_list_length()) {
 403     _young_list_fixed_length = 0;
 404   } else {
 405     _young_list_fixed_length = _young_gen_sizer->min_desired_young_length();
 406   }
 407   _free_regions_at_end_of_collection = _g1->free_regions();
 408   update_young_list_target_length();
 409   _prev_eden_capacity = _young_list_target_length * HeapRegion::GrainBytes;
 410 
 411   // We may immediately start allocating regions and placing them on the
 412   // collection set list. Initialize the per-collection set info
 413   start_incremental_cset_building();
 414 }
 415 
 416 // Create the jstat counters for the policy.
 417 void G1CollectorPolicy::initialize_gc_policy_counters() {
 418   _gc_policy_counters = new GCPolicyCounters("GarbageFirst", 1, 3);
 419 }
 420 
 421 bool G1CollectorPolicy::predict_will_fit(uint young_length,
 422                                          double base_time_ms,
 423                                          uint base_free_regions,
 424                                          double target_pause_time_ms) {
 425   if (young_length >= base_free_regions) {
 426     // end condition 1: not enough space for the young regions
 427     return false;
 428   }
 429 


 729       if (age < 0) {
 730         gclog_or_tty->print_cr("## %s: encountered negative age", name);
 731         ret = false;
 732       }
 733 
 734       if (age <= prev_age) {
 735         gclog_or_tty->print_cr("## %s: region ages are not strictly increasing "
 736                                "(%d, %d)", name, age, prev_age);
 737         ret = false;
 738       }
 739       prev_age = age;
 740     }
 741   }
 742 
 743   return ret;
 744 }
 745 #endif // PRODUCT
 746 
 747 void G1CollectorPolicy::record_full_collection_start() {
 748   _full_collection_start_sec = os::elapsedTime();

 749   // Release the future to-space so that it is available for compaction into.
 750   _g1->set_full_collection();
 751 }
 752 
 753 void G1CollectorPolicy::record_full_collection_end() {
 754   // Consider this like a collection pause for the purposes of allocation
 755   // since last pause.
 756   double end_sec = os::elapsedTime();
 757   double full_gc_time_sec = end_sec - _full_collection_start_sec;
 758   double full_gc_time_ms = full_gc_time_sec * 1000.0;
 759 
 760   _trace_gen1_time_data.record_full_collection(full_gc_time_ms);
 761 
 762   update_recent_gc_times(end_sec, full_gc_time_ms);
 763 
 764   _g1->clear_full_collection();
 765 
 766   // "Nuke" the heuristics that control the young/mixed GC
 767   // transitions and make sure we start with young GCs after the Full GC.
 768   set_gcs_are_young(true);


 771   clear_during_initial_mark_pause();
 772   _in_marking_window = false;
 773   _in_marking_window_im = false;
 774 
 775   _short_lived_surv_rate_group->start_adding_regions();
 776   // also call this on any additional surv rate groups
 777 
 778   record_survivor_regions(0, NULL, NULL);
 779 
 780   _free_regions_at_end_of_collection = _g1->free_regions();
 781   // Reset survivors SurvRateGroup.
 782   _survivor_surv_rate_group->reset();
 783   update_young_list_target_length();
 784   _collectionSetChooser->clear();
 785 }
 786 
 787 void G1CollectorPolicy::record_stop_world_start() {
 788   _stop_world_start = os::elapsedTime();
 789 }
 790 
 791 void G1CollectorPolicy::record_collection_pause_start(double start_time_sec,
 792                                                       size_t start_used) {
 793   // We only need to do this here as the policy will only be applied
 794   // to the GC we're about to start. so, no point is calculating this
 795   // every time we calculate / recalculate the target young length.
 796   update_survivors_policy();
 797 
 798   assert(_g1->used() == _g1->recalculate_used(),
 799          err_msg("sanity, used: "SIZE_FORMAT" recalculate_used: "SIZE_FORMAT,
 800                  _g1->used(), _g1->recalculate_used()));
 801 
 802   double s_w_t_ms = (start_time_sec - _stop_world_start) * 1000.0;
 803   _trace_gen0_time_data.record_start_collection(s_w_t_ms);
 804   _stop_world_start = 0.0;
 805 


 806   phase_times()->record_cur_collection_start_sec(start_time_sec);
 807   _cur_collection_pause_used_at_start_bytes = start_used;
 808   _cur_collection_pause_used_regions_at_start = _g1->used_regions();
 809   _pending_cards = _g1->pending_card_num();
 810 
 811   _collection_set_bytes_used_before = 0;
 812   _bytes_copied_during_gc = 0;
 813 
 814   YoungList* young_list = _g1->young_list();
 815   _eden_bytes_before_gc = young_list->eden_used_bytes();
 816   _survivor_bytes_before_gc = young_list->survivor_used_bytes();
 817   _capacity_before_gc = _g1->capacity();
 818 
 819   _last_gc_was_young = false;
 820 
 821   // do that for any other surv rate groups
 822   _short_lived_surv_rate_group->stop_adding_regions();
 823   _survivors_age_table.clear();
 824 
 825   assert( verify_young_ages(), "region age verification" );
 826 }
 827 
 828 void G1CollectorPolicy::record_concurrent_mark_init_end(double
 829                                                    mark_init_elapsed_time_ms) {
 830   _during_marking = true;
 831   assert(!initiate_conc_mark_if_possible(), "we should have cleared it by now");
 832   clear_during_initial_mark_pause();
 833   _cur_mark_stop_world_time_ms = mark_init_elapsed_time_ms;
 834 }
 835 
 836 void G1CollectorPolicy::record_concurrent_mark_remark_start() {
 837   _mark_remark_start_sec = os::elapsedTime();
 838   _during_marking = false;


1139   }
1140 
1141   _in_marking_window = new_in_marking_window;
1142   _in_marking_window_im = new_in_marking_window_im;
1143   _free_regions_at_end_of_collection = _g1->free_regions();
1144   update_young_list_target_length();
1145 
1146   // Note that _mmu_tracker->max_gc_time() returns the time in seconds.
1147   double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
1148   adjust_concurrent_refinement(phase_times()->average_last_update_rs_time(),
1149                                phase_times()->sum_last_update_rs_processed_buffers(), update_rs_time_goal_ms);
1150 
1151   _collectionSetChooser->verify();
1152 }
1153 
1154 #define EXT_SIZE_FORMAT "%.1f%s"
1155 #define EXT_SIZE_PARAMS(bytes)                                  \
1156   byte_size_in_proper_unit((double)(bytes)),                    \
1157   proper_unit_for_byte_size((bytes))
1158 















1159 void G1CollectorPolicy::print_heap_transition() {
1160   _g1->print_size_transition(gclog_or_tty,
1161     _cur_collection_pause_used_at_start_bytes, _g1->used(), _g1->capacity());
1162 }
1163 
1164 void G1CollectorPolicy::print_detailed_heap_transition() {
1165     YoungList* young_list = _g1->young_list();
1166     size_t eden_bytes = young_list->eden_used_bytes();
1167     size_t survivor_bytes = young_list->survivor_used_bytes();
1168     size_t used_before_gc = _cur_collection_pause_used_at_start_bytes;
1169     size_t used = _g1->used();
1170     size_t capacity = _g1->capacity();
1171     size_t eden_capacity =
1172       (_young_list_target_length * HeapRegion::GrainBytes) - survivor_bytes;
1173 
1174     gclog_or_tty->print_cr(
1175       "   [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") "
1176       "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
1177       "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
1178       EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
1179       EXT_SIZE_PARAMS(_eden_bytes_before_gc),
1180       EXT_SIZE_PARAMS(_prev_eden_capacity),
1181       EXT_SIZE_PARAMS(eden_bytes),
1182       EXT_SIZE_PARAMS(eden_capacity),
1183       EXT_SIZE_PARAMS(_survivor_bytes_before_gc),
1184       EXT_SIZE_PARAMS(survivor_bytes),
1185       EXT_SIZE_PARAMS(used_before_gc),
1186       EXT_SIZE_PARAMS(_capacity_before_gc),
1187       EXT_SIZE_PARAMS(used),
1188       EXT_SIZE_PARAMS(capacity));
1189 
1190     _prev_eden_capacity = eden_capacity;
1191 }
1192 
1193 void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
1194                                                      double update_rs_processed_buffers,
1195                                                      double goal_ms) {
1196   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
1197   ConcurrentG1Refine *cg1r = G1CollectedHeap::heap()->concurrent_g1_refine();
1198 
1199   if (G1UseAdaptiveConcRefinement) {
1200     const int k_gy = 3, k_gr = 6;
1201     const double inc_k = 1.1, dec_k = 0.9;
1202 
1203     int g = cg1r->green_zone();
1204     if (update_rs_time > goal_ms) {
1205       g = (int)(g * dec_k);  // Can become 0, that's OK. That would mean a mutator-only processing.
1206     } else {
1207       if (update_rs_time < goal_ms && update_rs_processed_buffers > g) {
1208         g = (int)MAX2(g * inc_k, g + 1.0);
1209       }
1210     }


   1 /*
   2  * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 389   }
 390 
 391   assert(_min_desired_young_length <= _max_desired_young_length, "Invalid min/max young gen size values");
 392 }
 393 
 394 void G1CollectorPolicy::init() {
 395   // Set aside an initial future to_space.
 396   _g1 = G1CollectedHeap::heap();
 397 
 398   assert(Heap_lock->owned_by_self(), "Locking discipline.");
 399 
 400   initialize_gc_policy_counters();
 401 
 402   if (adaptive_young_list_length()) {
 403     _young_list_fixed_length = 0;
 404   } else {
 405     _young_list_fixed_length = _young_gen_sizer->min_desired_young_length();
 406   }
 407   _free_regions_at_end_of_collection = _g1->free_regions();
 408   update_young_list_target_length();

 409 
 410   // We may immediately start allocating regions and placing them on the
 411   // collection set list. Initialize the per-collection set info
 412   start_incremental_cset_building();
 413 }
 414 
 415 // Create the jstat counters for the policy.
 416 void G1CollectorPolicy::initialize_gc_policy_counters() {
 417   _gc_policy_counters = new GCPolicyCounters("GarbageFirst", 1, 3);
 418 }
 419 
 420 bool G1CollectorPolicy::predict_will_fit(uint young_length,
 421                                          double base_time_ms,
 422                                          uint base_free_regions,
 423                                          double target_pause_time_ms) {
 424   if (young_length >= base_free_regions) {
 425     // end condition 1: not enough space for the young regions
 426     return false;
 427   }
 428 


 728       if (age < 0) {
 729         gclog_or_tty->print_cr("## %s: encountered negative age", name);
 730         ret = false;
 731       }
 732 
 733       if (age <= prev_age) {
 734         gclog_or_tty->print_cr("## %s: region ages are not strictly increasing "
 735                                "(%d, %d)", name, age, prev_age);
 736         ret = false;
 737       }
 738       prev_age = age;
 739     }
 740   }
 741 
 742   return ret;
 743 }
 744 #endif // PRODUCT
 745 
 746 void G1CollectorPolicy::record_full_collection_start() {
 747   _full_collection_start_sec = os::elapsedTime();
 748   record_heap_size_info_at_start();
 749   // Release the future to-space so that it is available for compaction into.
 750   _g1->set_full_collection();
 751 }
 752 
 753 void G1CollectorPolicy::record_full_collection_end() {
 754   // Consider this like a collection pause for the purposes of allocation
 755   // since last pause.
 756   double end_sec = os::elapsedTime();
 757   double full_gc_time_sec = end_sec - _full_collection_start_sec;
 758   double full_gc_time_ms = full_gc_time_sec * 1000.0;
 759 
 760   _trace_gen1_time_data.record_full_collection(full_gc_time_ms);
 761 
 762   update_recent_gc_times(end_sec, full_gc_time_ms);
 763 
 764   _g1->clear_full_collection();
 765 
 766   // "Nuke" the heuristics that control the young/mixed GC
 767   // transitions and make sure we start with young GCs after the Full GC.
 768   set_gcs_are_young(true);


 771   clear_during_initial_mark_pause();
 772   _in_marking_window = false;
 773   _in_marking_window_im = false;
 774 
 775   _short_lived_surv_rate_group->start_adding_regions();
 776   // also call this on any additional surv rate groups
 777 
 778   record_survivor_regions(0, NULL, NULL);
 779 
 780   _free_regions_at_end_of_collection = _g1->free_regions();
 781   // Reset survivors SurvRateGroup.
 782   _survivor_surv_rate_group->reset();
 783   update_young_list_target_length();
 784   _collectionSetChooser->clear();
 785 }
 786 
 787 void G1CollectorPolicy::record_stop_world_start() {
 788   _stop_world_start = os::elapsedTime();
 789 }
 790 
 791 void G1CollectorPolicy::record_collection_pause_start(double start_time_sec) {

 792   // We only need to do this here as the policy will only be applied
 793   // to the GC we're about to start. so, no point is calculating this
 794   // every time we calculate / recalculate the target young length.
 795   update_survivors_policy();
 796 
 797   assert(_g1->used() == _g1->recalculate_used(),
 798          err_msg("sanity, used: "SIZE_FORMAT" recalculate_used: "SIZE_FORMAT,
 799                  _g1->used(), _g1->recalculate_used()));
 800 
 801   double s_w_t_ms = (start_time_sec - _stop_world_start) * 1000.0;
 802   _trace_gen0_time_data.record_start_collection(s_w_t_ms);
 803   _stop_world_start = 0.0;
 804 
 805   record_heap_size_info_at_start();
 806 
 807   phase_times()->record_cur_collection_start_sec(start_time_sec);


 808   _pending_cards = _g1->pending_card_num();
 809 
 810   _collection_set_bytes_used_before = 0;
 811   _bytes_copied_during_gc = 0;
 812 





 813   _last_gc_was_young = false;
 814 
 815   // do that for any other surv rate groups
 816   _short_lived_surv_rate_group->stop_adding_regions();
 817   _survivors_age_table.clear();
 818 
 819   assert( verify_young_ages(), "region age verification" );
 820 }
 821 
 822 void G1CollectorPolicy::record_concurrent_mark_init_end(double
 823                                                    mark_init_elapsed_time_ms) {
 824   _during_marking = true;
 825   assert(!initiate_conc_mark_if_possible(), "we should have cleared it by now");
 826   clear_during_initial_mark_pause();
 827   _cur_mark_stop_world_time_ms = mark_init_elapsed_time_ms;
 828 }
 829 
 830 void G1CollectorPolicy::record_concurrent_mark_remark_start() {
 831   _mark_remark_start_sec = os::elapsedTime();
 832   _during_marking = false;


1133   }
1134 
1135   _in_marking_window = new_in_marking_window;
1136   _in_marking_window_im = new_in_marking_window_im;
1137   _free_regions_at_end_of_collection = _g1->free_regions();
1138   update_young_list_target_length();
1139 
1140   // Note that _mmu_tracker->max_gc_time() returns the time in seconds.
1141   double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
1142   adjust_concurrent_refinement(phase_times()->average_last_update_rs_time(),
1143                                phase_times()->sum_last_update_rs_processed_buffers(), update_rs_time_goal_ms);
1144 
1145   _collectionSetChooser->verify();
1146 }
1147 
1148 #define EXT_SIZE_FORMAT "%.1f%s"
1149 #define EXT_SIZE_PARAMS(bytes)                                  \
1150   byte_size_in_proper_unit((double)(bytes)),                    \
1151   proper_unit_for_byte_size((bytes))
1152 
1153 void G1CollectorPolicy::record_heap_size_info_at_start() {
1154   YoungList* young_list = _g1->young_list();
1155   _eden_bytes_before_gc = young_list->eden_used_bytes();
1156   _survivor_bytes_before_gc = young_list->survivor_used_bytes();
1157   _capacity_before_gc = _g1->capacity();
1158 
1159   _cur_collection_pause_used_at_start_bytes = _g1->used();
1160   _cur_collection_pause_used_regions_at_start = _g1->used_regions();
1161 
1162   size_t eden_capacity_before_gc =
1163          (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_bytes_before_gc;
1164 
1165   _prev_eden_capacity = eden_capacity_before_gc;
1166 }
1167 
1168 void G1CollectorPolicy::print_heap_transition() {
1169   _g1->print_size_transition(gclog_or_tty,
1170     _cur_collection_pause_used_at_start_bytes, _g1->used(), _g1->capacity());
1171 }
1172 
1173 void G1CollectorPolicy::print_detailed_heap_transition() {
1174     YoungList* young_list = _g1->young_list();
1175     size_t eden_bytes = young_list->eden_used_bytes();
1176     size_t survivor_bytes = young_list->survivor_used_bytes();
1177     size_t used_before_gc = _cur_collection_pause_used_at_start_bytes;
1178     size_t used = _g1->used();
1179     size_t capacity = _g1->capacity();
1180     size_t eden_capacity =
1181       (_young_list_target_length * HeapRegion::GrainBytes) - survivor_bytes;
1182 
1183     gclog_or_tty->print_cr(
1184       "   [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") "
1185       "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
1186       "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
1187       EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
1188       EXT_SIZE_PARAMS(_eden_bytes_before_gc),
1189       EXT_SIZE_PARAMS(_prev_eden_capacity),
1190       EXT_SIZE_PARAMS(eden_bytes),
1191       EXT_SIZE_PARAMS(eden_capacity),
1192       EXT_SIZE_PARAMS(_survivor_bytes_before_gc),
1193       EXT_SIZE_PARAMS(survivor_bytes),
1194       EXT_SIZE_PARAMS(used_before_gc),
1195       EXT_SIZE_PARAMS(_capacity_before_gc),
1196       EXT_SIZE_PARAMS(used),
1197       EXT_SIZE_PARAMS(capacity));


1198 }
1199 
1200 void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
1201                                                      double update_rs_processed_buffers,
1202                                                      double goal_ms) {
1203   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
1204   ConcurrentG1Refine *cg1r = G1CollectedHeap::heap()->concurrent_g1_refine();
1205 
1206   if (G1UseAdaptiveConcRefinement) {
1207     const int k_gy = 3, k_gr = 6;
1208     const double inc_k = 1.1, dec_k = 0.9;
1209 
1210     int g = cg1r->green_zone();
1211     if (update_rs_time > goal_ms) {
1212       g = (int)(g * dec_k);  // Can become 0, that's OK. That would mean a mutator-only processing.
1213     } else {
1214       if (update_rs_time < goal_ms && update_rs_processed_buffers > g) {
1215         g = (int)MAX2(g * inc_k, g + 1.0);
1216       }
1217     }