src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54833 76751d3faf7b
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
    33 
    33 
    34 ShenandoahAdaptiveHeuristics::ShenandoahAdaptiveHeuristics() :
    34 ShenandoahAdaptiveHeuristics::ShenandoahAdaptiveHeuristics() :
    35   ShenandoahHeuristics(),
    35   ShenandoahHeuristics(),
    36   _cycle_gap_history(new TruncatedSeq(5)),
    36   _cycle_gap_history(new TruncatedSeq(5)),
    37   _conc_mark_duration_history(new TruncatedSeq(5)),
    37   _conc_mark_duration_history(new TruncatedSeq(5)),
    38   _conc_uprefs_duration_history(new TruncatedSeq(5)) {
    38   _conc_uprefs_duration_history(new TruncatedSeq(5)) {}
    39 
       
    40   SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent);
       
    41   SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent);
       
    42 
       
    43   // Final configuration checks
       
    44   SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier);
       
    45   SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier);
       
    46   SHENANDOAH_CHECK_FLAG_SET(ShenandoahKeepAliveBarrier);
       
    47   SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier);
       
    48   SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier);
       
    49 }
       
    50 
    39 
    51 ShenandoahAdaptiveHeuristics::~ShenandoahAdaptiveHeuristics() {}
    40 ShenandoahAdaptiveHeuristics::~ShenandoahAdaptiveHeuristics() {}
    52 
    41 
    53 void ShenandoahAdaptiveHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset,
    42 void ShenandoahAdaptiveHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset,
    54                                                                          RegionData* data, size_t size,
    43                                                                          RegionData* data, size_t size,
    75   size_t capacity    = ShenandoahHeap::heap()->max_capacity();
    64   size_t capacity    = ShenandoahHeap::heap()->max_capacity();
    76   size_t free_target = capacity / 100 * ShenandoahMinFreeThreshold;
    65   size_t free_target = capacity / 100 * ShenandoahMinFreeThreshold;
    77   size_t min_garbage = free_target > actual_free ? (free_target - actual_free) : 0;
    66   size_t min_garbage = free_target > actual_free ? (free_target - actual_free) : 0;
    78   size_t max_cset    = (size_t)((1.0 * capacity / 100 * ShenandoahEvacReserve) / ShenandoahEvacWaste);
    67   size_t max_cset    = (size_t)((1.0 * capacity / 100 * ShenandoahEvacReserve) / ShenandoahEvacWaste);
    79 
    68 
    80   log_info(gc, ergo)("Adaptive CSet Selection. Target Free: " SIZE_FORMAT "M, Actual Free: "
    69   log_info(gc, ergo)("Adaptive CSet Selection. Target Free: " SIZE_FORMAT "%s, Actual Free: "
    81                      SIZE_FORMAT "M, Max CSet: " SIZE_FORMAT "M, Min Garbage: " SIZE_FORMAT "M",
    70                      SIZE_FORMAT "%s, Max CSet: " SIZE_FORMAT "%s, Min Garbage: " SIZE_FORMAT "%s",
    82                      free_target / M, actual_free / M, max_cset / M, min_garbage / M);
    71                      byte_size_in_proper_unit(free_target), proper_unit_for_byte_size(free_target),
       
    72                      byte_size_in_proper_unit(actual_free), proper_unit_for_byte_size(actual_free),
       
    73                      byte_size_in_proper_unit(max_cset),    proper_unit_for_byte_size(max_cset),
       
    74                      byte_size_in_proper_unit(min_garbage), proper_unit_for_byte_size(min_garbage));
    83 
    75 
    84   // Better select garbage-first regions
    76   // Better select garbage-first regions
    85   QuickSort::sort<RegionData>(data, (int)size, compare_by_garbage, false);
    77   QuickSort::sort<RegionData>(data, (int)size, compare_by_garbage, false);
    86 
    78 
    87   size_t cur_cset = 0;
    79   size_t cur_cset = 0;
   119   } else if (phase == ShenandoahPhaseTimings::conc_update_refs) {
   111   } else if (phase == ShenandoahPhaseTimings::conc_update_refs) {
   120     _conc_uprefs_duration_history->add(secs);
   112     _conc_uprefs_duration_history->add(secs);
   121   } // Else ignore
   113   } // Else ignore
   122 }
   114 }
   123 
   115 
   124 bool ShenandoahAdaptiveHeuristics::should_start_normal_gc() const {
   116 bool ShenandoahAdaptiveHeuristics::should_start_gc() const {
   125   ShenandoahHeap* heap = ShenandoahHeap::heap();
   117   ShenandoahHeap* heap = ShenandoahHeap::heap();
   126   size_t capacity = heap->max_capacity();
   118   size_t capacity = heap->max_capacity();
   127   size_t available = heap->free_set()->available();
   119   size_t available = heap->free_set()->available();
   128 
   120 
   129   // Check if we are falling below the worst limit, time to trigger the GC, regardless of
   121   // Check if we are falling below the worst limit, time to trigger the GC, regardless of
   130   // anything else.
   122   // anything else.
   131   size_t min_threshold = capacity / 100 * ShenandoahMinFreeThreshold;
   123   size_t min_threshold = capacity / 100 * ShenandoahMinFreeThreshold;
   132   if (available < min_threshold) {
   124   if (available < min_threshold) {
   133     log_info(gc)("Trigger: Free (" SIZE_FORMAT "M) is below minimum threshold (" SIZE_FORMAT "M)",
   125     log_info(gc)("Trigger: Free (" SIZE_FORMAT "%s) is below minimum threshold (" SIZE_FORMAT "%s)",
   134                  available / M, min_threshold / M);
   126                  byte_size_in_proper_unit(available),     proper_unit_for_byte_size(available),
       
   127                  byte_size_in_proper_unit(min_threshold), proper_unit_for_byte_size(min_threshold));
   135     return true;
   128     return true;
   136   }
   129   }
   137 
   130 
   138   // Check if are need to learn a bit about the application
   131   // Check if are need to learn a bit about the application
   139   const size_t max_learn = ShenandoahLearningSteps;
   132   const size_t max_learn = ShenandoahLearningSteps;
   140   if (_gc_times_learned < max_learn) {
   133   if (_gc_times_learned < max_learn) {
   141     size_t init_threshold = capacity / 100 * ShenandoahInitFreeThreshold;
   134     size_t init_threshold = capacity / 100 * ShenandoahInitFreeThreshold;
   142     if (available < init_threshold) {
   135     if (available < init_threshold) {
   143       log_info(gc)("Trigger: Learning " SIZE_FORMAT " of " SIZE_FORMAT ". Free (" SIZE_FORMAT "M) is below initial threshold (" SIZE_FORMAT "M)",
   136       log_info(gc)("Trigger: Learning " SIZE_FORMAT " of " SIZE_FORMAT ". Free (" SIZE_FORMAT "%s) is below initial threshold (" SIZE_FORMAT "%s)",
   144                    _gc_times_learned + 1, max_learn, available / M, init_threshold / M);
   137                    _gc_times_learned + 1, max_learn,
       
   138                    byte_size_in_proper_unit(available),      proper_unit_for_byte_size(available),
       
   139                    byte_size_in_proper_unit(init_threshold), proper_unit_for_byte_size(init_threshold));
   145       return true;
   140       return true;
   146     }
   141     }
   147   }
   142   }
   148 
   143 
   149   // Check if allocation headroom is still okay. This also factors in:
   144   // Check if allocation headroom is still okay. This also factors in:
   163   double average_gc = _gc_time_history->avg();
   158   double average_gc = _gc_time_history->avg();
   164   double time_since_last = time_since_last_gc();
   159   double time_since_last = time_since_last_gc();
   165   double allocation_rate = heap->bytes_allocated_since_gc_start() / time_since_last;
   160   double allocation_rate = heap->bytes_allocated_since_gc_start() / time_since_last;
   166 
   161 
   167   if (average_gc > allocation_headroom / allocation_rate) {
   162   if (average_gc > allocation_headroom / allocation_rate) {
   168     log_info(gc)("Trigger: Average GC time (%.2f ms) is above the time for allocation rate (%.2f MB/s) to deplete free headroom (" SIZE_FORMAT "M)",
   163     log_info(gc)("Trigger: Average GC time (%.2f ms) is above the time for allocation rate (%.0f %sB/s) to deplete free headroom (" SIZE_FORMAT "%s)",
   169                  average_gc * 1000, allocation_rate / M, allocation_headroom / M);
   164                  average_gc * 1000,
   170     log_info(gc, ergo)("Free headroom: " SIZE_FORMAT "M (free) - " SIZE_FORMAT "M (spike) - " SIZE_FORMAT "M (penalties) = " SIZE_FORMAT "M",
   165                  byte_size_in_proper_unit(allocation_rate),     proper_unit_for_byte_size(allocation_rate),
   171                        available / M, spike_headroom / M, penalties / M, allocation_headroom / M);
   166                  byte_size_in_proper_unit(allocation_headroom), proper_unit_for_byte_size(allocation_headroom));
       
   167     log_info(gc, ergo)("Free headroom: " SIZE_FORMAT "%s (free) - " SIZE_FORMAT "%s (spike) - " SIZE_FORMAT "%s (penalties) = " SIZE_FORMAT "%s",
       
   168                  byte_size_in_proper_unit(available),           proper_unit_for_byte_size(available),
       
   169                  byte_size_in_proper_unit(spike_headroom),      proper_unit_for_byte_size(spike_headroom),
       
   170                  byte_size_in_proper_unit(penalties),           proper_unit_for_byte_size(penalties),
       
   171                  byte_size_in_proper_unit(allocation_headroom), proper_unit_for_byte_size(allocation_headroom));
   172     return true;
   172     return true;
   173   }
   173   }
   174 
   174 
   175   return ShenandoahHeuristics::should_start_normal_gc();
   175   return ShenandoahHeuristics::should_start_gc();
   176 }
   176 }
   177 
   177 
   178 bool ShenandoahAdaptiveHeuristics::should_start_update_refs() {
   178 bool ShenandoahAdaptiveHeuristics::should_start_update_refs() {
   179   if (! _update_refs_adaptive) {
   179   if (! _update_refs_adaptive) {
   180     return _update_refs_early;
   180     return _update_refs_early;