< prev index next >

src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp

Print this page

  1 /*
  2  * Copyright (c) 2018, 2019, Red Hat, Inc. 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  *
 23  */
 24 
 25 #ifndef SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHHEURISTICS_HPP
 26 #define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHHEURISTICS_HPP
 27 
 28 #include "gc/shenandoah/shenandoahHeap.hpp"
 29 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
 30 #include "gc/shenandoah/shenandoahSharedVariables.hpp"
 31 #include "memory/allocation.hpp"
 32 #include "runtime/globals_extension.hpp"

 33 
 34 #define SHENANDOAH_ERGO_DISABLE_FLAG(name)                                  \
 35   do {                                                                      \
 36     if (FLAG_IS_DEFAULT(name) && (name)) {                                  \
 37       log_info(gc)("Heuristics ergonomically sets -XX:-" #name);            \
 38       FLAG_SET_DEFAULT(name, false);                                        \
 39     }                                                                       \
 40   } while (0)
 41 
 42 #define SHENANDOAH_ERGO_ENABLE_FLAG(name)                                   \
 43   do {                                                                      \
 44     if (FLAG_IS_DEFAULT(name) && !(name)) {                                 \
 45       log_info(gc)("Heuristics ergonomically sets -XX:+" #name);            \
 46       FLAG_SET_DEFAULT(name, true);                                         \
 47     }                                                                       \
 48   } while (0)
 49 
 50 #define SHENANDOAH_ERGO_OVERRIDE_DEFAULT(name, value)                       \
 51   do {                                                                      \
 52     if (FLAG_IS_DEFAULT(name)) {                                            \
 53       log_info(gc)("Heuristics ergonomically sets -XX:" #name "=" #value);  \
 54       FLAG_SET_DEFAULT(name, value);                                        \
 55     }                                                                       \
 56   } while (0)
 57 
 58 class ShenandoahCollectionSet;
 59 class ShenandoahHeapRegion;
 60 





 61 class ShenandoahHeuristics : public CHeapObj<mtGC> {
 62   static const intx Concurrent_Adjust   = -1; // recover from penalties
 63   static const intx Degenerated_Penalty = 10; // how much to penalize average GC duration history on Degenerated GC
 64   static const intx Full_Penalty        = 20; // how much to penalize average GC duration history on Full GC
 65 









 66 protected:
 67   typedef struct {















 68     ShenandoahHeapRegion* _region;
 69     size_t _garbage;
 70   } RegionData;
 71 





























































 72   RegionData* _region_data;
 73 
 74   uint _degenerated_cycles_in_a_row;
 75   uint _successful_cycles_in_a_row;
 76 
 77   double _cycle_start;
 78   double _last_cycle_end;
 79 
 80   size_t _gc_times_learned;
 81   intx _gc_time_penalties;
 82   TruncatedSeq* _gc_time_history;
 83 
 84   // There may be many threads that contend to set this flag
 85   ShenandoahSharedFlag _metaspace_oom;
 86 
 87   static int compare_by_garbage(RegionData a, RegionData b);
 88 
 89   virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* set,
 90                                                      RegionData* data, size_t data_size,
 91                                                      size_t free) = 0;
 92 
 93   void adjust_penalty(intx step);
 94 










 95 public:
 96   ShenandoahHeuristics();
 97   virtual ~ShenandoahHeuristics();
 98 
 99   void record_metaspace_oom()     { _metaspace_oom.set(); }
100   void clear_metaspace_oom()      { _metaspace_oom.unset(); }
101   bool has_metaspace_oom() const  { return _metaspace_oom.is_set(); }
102 




103   virtual void record_cycle_start();
104 
105   virtual void record_cycle_end();
106 
107   virtual bool should_start_gc();
108 




109   virtual bool should_degenerate_cycle();
110 
111   virtual void record_success_concurrent();
112 
113   virtual void record_success_degenerated();
114 
115   virtual void record_success_full();
116 
117   virtual void record_allocation_failure_gc();
118 
119   virtual void record_requested_gc();
120 
121   virtual void choose_collection_set(ShenandoahCollectionSet* collection_set);
122 
123   virtual bool can_unload_classes();



124   virtual bool should_unload_classes();
125 
126   virtual const char* name() = 0;
127   virtual bool is_diagnostic() = 0;
128   virtual bool is_experimental() = 0;
129   virtual void initialize();
130 
131   double time_since_last_gc() const;



132 };
133 
134 #endif // SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHHEURISTICS_HPP

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

 30 #include "gc/shenandoah/shenandoahSharedVariables.hpp"
 31 #include "memory/allocation.hpp"
 32 #include "runtime/globals_extension.hpp"
 33 #include "utilities/numberSeq.hpp"
 34 
 35 #define SHENANDOAH_ERGO_DISABLE_FLAG(name)                                  \
 36   do {                                                                      \
 37     if (FLAG_IS_DEFAULT(name) && (name)) {                                  \
 38       log_info(gc)("Heuristics ergonomically sets -XX:-" #name);            \
 39       FLAG_SET_DEFAULT(name, false);                                        \
 40     }                                                                       \
 41   } while (0)
 42 
 43 #define SHENANDOAH_ERGO_ENABLE_FLAG(name)                                   \
 44   do {                                                                      \
 45     if (FLAG_IS_DEFAULT(name) && !(name)) {                                 \
 46       log_info(gc)("Heuristics ergonomically sets -XX:+" #name);            \
 47       FLAG_SET_DEFAULT(name, true);                                         \
 48     }                                                                       \
 49   } while (0)
 50 
 51 #define SHENANDOAH_ERGO_OVERRIDE_DEFAULT(name, value)                       \
 52   do {                                                                      \
 53     if (FLAG_IS_DEFAULT(name)) {                                            \
 54       log_info(gc)("Heuristics ergonomically sets -XX:" #name "=" #value);  \
 55       FLAG_SET_DEFAULT(name, value);                                        \
 56     }                                                                       \
 57   } while (0)
 58 
 59 class ShenandoahCollectionSet;
 60 class ShenandoahHeapRegion;
 61 
 62 /*
 63  * Shenandoah heuristics are primarily responsible for deciding when to start
 64  * a collection cycle and choosing which regions will be evacuated during the
 65  * cycle.
 66  */
 67 class ShenandoahHeuristics : public CHeapObj<mtGC> {
 68   static const intx Concurrent_Adjust   = -1; // recover from penalties
 69   static const intx Degenerated_Penalty = 10; // how much to penalize average GC duration history on Degenerated GC
 70   static const intx Full_Penalty        = 20; // how much to penalize average GC duration history on Full GC
 71 
 72   // How many times can I decline a trigger opportunity without being penalized for excessive idle span before trigger?
 73   static const size_t Penalty_Free_Declinations = 16;
 74 
 75 #ifdef ASSERT
 76   enum UnionTag {
 77     is_uninitialized, is_garbage, is_live_data
 78   };
 79 #endif
 80 
 81 protected:
 82   static const uint Moving_Average_Samples = 10; // Number of samples to store in moving averages
 83 
 84   bool _start_gc_is_pending;              // True denotes that GC has been triggered, so no need to trigger again.
 85   size_t _declined_trigger_count;         // This counts how many times since previous GC finished that this
 86                                           //  heuristic has answered false to should_start_gc().
 87   size_t _most_recent_declined_trigger_count;
 88                                        ;  // This represents the value of _declined_trigger_count as captured at the
 89                                           //  moment the most recent GC effort was triggered.  In case the most recent
 90                                           //  concurrent GC effort degenerates, the value of this variable allows us to
 91                                           //  differentiate between degeneration because heuristic was overly optimistic
 92                                           //  in delaying the trigger vs. degeneration for other reasons (such as the
 93                                           //  most recent GC triggered "immediately" after previous GC finished, but the
 94                                           //  free headroom has already been depleted).
 95 
 96   class RegionData {
 97     private:
 98     ShenandoahHeapRegion* _region;
 99     union {
100       size_t _garbage;          // Not used by old-gen heuristics.
101       size_t _live_data;        // Only used for old-gen heuristics, which prioritizes retention of _live_data over garbage reclaim
102     } _region_union;
103 #ifdef ASSERT
104     UnionTag _union_tag;
105 #endif
106     public:
107 
108     inline void clear() {
109       _region = nullptr;
110       _region_union._garbage = 0;
111 #ifdef ASSERT
112       _union_tag = is_uninitialized;
113 #endif
114     }
115 
116     inline void set_region_and_garbage(ShenandoahHeapRegion* region, size_t garbage) {
117       _region = region;
118       _region_union._garbage = garbage;
119 #ifdef ASSERT
120       _union_tag = is_garbage;
121 #endif
122     }
123 
124     inline void set_region_and_livedata(ShenandoahHeapRegion* region, size_t live) {
125       _region = region;
126       _region_union._live_data = live;
127 #ifdef ASSERT
128       _union_tag = is_live_data;
129 #endif
130     }
131 
132     inline ShenandoahHeapRegion* get_region() const {
133       assert(_union_tag != is_uninitialized, "Cannot fetch region from uninitialized RegionData");
134       return _region;
135     }
136 
137     inline size_t get_garbage() const {
138       assert(_union_tag == is_garbage, "Invalid union fetch");
139       return _region_union._garbage;
140     }
141 
142     inline size_t get_livedata() const {
143       assert(_union_tag == is_live_data, "Invalid union fetch");
144       return _region_union._live_data;
145     }
146   };
147 
148   // Source of information about the memory space managed by this heuristic
149   ShenandoahSpaceInfo* _space_info;
150 
151   // Depending on generation mode, region data represents the results of the relevant
152   // most recently completed marking pass:
153   //   - in GLOBAL mode, global marking pass
154   //   - in OLD mode,    old-gen marking pass
155   //   - in YOUNG mode,  young-gen marking pass
156   //
157   // Note that there is some redundancy represented in region data because
158   // each instance is an array large enough to hold all regions. However,
159   // any region in young-gen is not in old-gen. And any time we are
160   // making use of the GLOBAL data, there is no need to maintain the
161   // YOUNG or OLD data. Consider this redundancy of data structure to
162   // have negligible cost unless proven otherwise.
163   RegionData* _region_data;
164 
165   size_t _guaranteed_gc_interval;

166 
167   double _cycle_start;
168   double _last_cycle_end;
169 
170   size_t _gc_times_learned;
171   intx _gc_time_penalties;
172   TruncatedSeq* _gc_cycle_time_history;
173 
174   // There may be many threads that contend to set this flag
175   ShenandoahSharedFlag _metaspace_oom;
176 
177   static int compare_by_garbage(RegionData a, RegionData b);
178 
179   virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* set,
180                                                      RegionData* data, size_t data_size,
181                                                      size_t free) = 0;
182 
183   void adjust_penalty(intx step);
184 
185   inline void accept_trigger() {
186     _most_recent_declined_trigger_count = _declined_trigger_count;
187     _declined_trigger_count = 0;
188     _start_gc_is_pending = true;
189   }
190 
191   inline void decline_trigger() {
192     _declined_trigger_count++;
193   }
194 
195 public:
196   ShenandoahHeuristics(ShenandoahSpaceInfo* space_info);
197   virtual ~ShenandoahHeuristics();
198 
199   void record_metaspace_oom()     { _metaspace_oom.set(); }
200   void clear_metaspace_oom()      { _metaspace_oom.unset(); }
201   bool has_metaspace_oom() const  { return _metaspace_oom.is_set(); }
202 
203   void set_guaranteed_gc_interval(size_t guaranteed_gc_interval) {
204     _guaranteed_gc_interval = guaranteed_gc_interval;
205   }
206 
207   virtual void record_cycle_start();
208 
209   virtual void record_cycle_end();
210 
211   virtual bool should_start_gc();
212 
213   inline void cancel_trigger_request() {
214     _start_gc_is_pending = false;
215   }
216 
217   virtual bool should_degenerate_cycle();
218 
219   virtual void record_success_concurrent();
220 
221   virtual void record_success_degenerated();
222 
223   virtual void record_success_full();
224 
225   virtual void record_allocation_failure_gc();
226 
227   virtual void record_requested_gc();
228 
229   virtual void choose_collection_set(ShenandoahCollectionSet* collection_set);
230 
231   virtual bool can_unload_classes();
232 
233   // This indicates whether or not the current cycle should unload classes.
234   // It does NOT indicate that a cycle should be started.
235   virtual bool should_unload_classes();
236 
237   virtual const char* name() = 0;
238   virtual bool is_diagnostic() = 0;
239   virtual bool is_experimental() = 0;
240   virtual void initialize();
241 
242   double elapsed_cycle_time() const;
243 
244   // Format prefix and emit log message indicating a GC cycle hs been triggered
245   void log_trigger(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3);
246 };
247 
248 #endif // SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHHEURISTICS_HPP
< prev index next >