1 /* 2 * Copyright (c) 2013, 2018, Red Hat, Inc. and/or its affiliates. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 * 22 */ 23 24 #include "precompiled.hpp" 25 #include "gc_implementation/shared/gcTimer.hpp" 26 #include "gc_implementation/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp" 27 #include "gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp" 28 #include "gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.hpp" 29 #include "gc_implementation/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp" 30 #include "gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.hpp" 31 #include "gc_implementation/shenandoah/shenandoahCollectionSet.hpp" 32 #include "gc_implementation/shenandoah/shenandoahCollectorPolicy.hpp" 33 #include "gc_implementation/shenandoah/shenandoahFreeSet.hpp" 34 #include "gc_implementation/shenandoah/shenandoahHeuristics.hpp" 35 #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" 36 #include "gc_implementation/shenandoah/shenandoahLogging.hpp" 37 38 void ShenandoahCollectorPolicy::record_gc_start() { 39 _heuristics->record_gc_start(); 40 } 41 42 void ShenandoahCollectorPolicy::record_gc_end() { 43 _heuristics->record_gc_end(); 44 } 45 46 ShenandoahCollectorPolicy::ShenandoahCollectorPolicy() : 47 _cycle_counter(0), 48 _success_concurrent_gcs(0), 49 _success_partial_gcs(0), 50 _success_degenerated_gcs(0), 51 _success_full_gcs(0), 52 _explicit_concurrent(0), 53 _explicit_full(0), 54 _alloc_failure_degenerated(0), 55 _alloc_failure_full(0), 56 _alloc_failure_degenerated_upgrade_to_full(0) 57 { 58 Copy::zero_to_bytes(_degen_points, sizeof(size_t) * ShenandoahHeap::_DEGENERATED_LIMIT); 59 60 ShenandoahHeapRegion::setup_heap_region_size(initial_heap_byte_size(), max_heap_byte_size()); 61 62 initialize_all(); 63 64 _tracer = new (ResourceObj::C_HEAP, mtGC) ShenandoahTracer(); 65 66 if (ShenandoahGCHeuristics != NULL) { 67 if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { 68 _heuristics = new ShenandoahAggressiveHeuristics(); 69 } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) { 70 _heuristics = new ShenandoahStaticHeuristics(); 71 } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) { 72 _heuristics = new ShenandoahAdaptiveHeuristics(); 73 } else if (strcmp(ShenandoahGCHeuristics, "passive") == 0) { 74 _heuristics = new ShenandoahPassiveHeuristics(); 75 } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) { 76 _heuristics = new ShenandoahCompactHeuristics(); 77 } else { 78 vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option"); 79 } 80 81 if (_heuristics->is_diagnostic() && !UnlockDiagnosticVMOptions) { 82 vm_exit_during_initialization( 83 err_msg("Heuristics \"%s\" is diagnostic, and must be enabled via -XX:+UnlockDiagnosticVMOptions.", 84 _heuristics->name())); 85 } 86 if (_heuristics->is_experimental() && !UnlockExperimentalVMOptions) { 87 vm_exit_during_initialization( 88 err_msg("Heuristics \"%s\" is experimental, and must be enabled via -XX:+UnlockExperimentalVMOptions.", 89 _heuristics->name())); 90 } 91 log_info(gc, init)("Shenandoah heuristics: %s", 92 _heuristics->name()); 93 _heuristics->print_thresholds(); 94 } else { 95 ShouldNotReachHere(); 96 } 97 } 98 99 ShenandoahCollectorPolicy* ShenandoahCollectorPolicy::as_pgc_policy() { 100 return this; 101 } 102 103 BarrierSet::Name ShenandoahCollectorPolicy::barrier_set_name() { 104 return BarrierSet::ShenandoahBarrierSet; 105 } 106 107 HeapWord* ShenandoahCollectorPolicy::mem_allocate_work(size_t size, 108 bool is_tlab, 109 bool* gc_overhead_limit_was_exceeded) { 110 guarantee(false, "Not using this policy feature yet."); 111 return NULL; 112 } 113 114 HeapWord* ShenandoahCollectorPolicy::satisfy_failed_allocation(size_t size, bool is_tlab) { 115 guarantee(false, "Not using this policy feature yet."); 116 return NULL; 117 } 118 119 void ShenandoahCollectorPolicy::initialize_alignments() { 120 121 // This is expected by our algorithm for ShenandoahHeap::heap_region_containing(). 122 _space_alignment = ShenandoahHeapRegion::region_size_bytes(); 123 _heap_alignment = ShenandoahHeapRegion::region_size_bytes(); 124 } 125 126 void ShenandoahCollectorPolicy::post_heap_initialize() { 127 // Nothing to do here (yet). 128 } 129 130 void ShenandoahCollectorPolicy::record_explicit_to_concurrent() { 131 _heuristics->record_explicit_gc(); 132 _explicit_concurrent++; 133 } 134 135 void ShenandoahCollectorPolicy::record_explicit_to_full() { 136 _heuristics->record_explicit_gc(); 137 _explicit_full++; 138 } 139 140 void ShenandoahCollectorPolicy::record_alloc_failure_to_full() { 141 _heuristics->record_allocation_failure_gc(); 142 _alloc_failure_full++; 143 } 144 145 void ShenandoahCollectorPolicy::record_alloc_failure_to_degenerated(ShenandoahHeap::ShenandoahDegenPoint point) { 146 assert(point < ShenandoahHeap::_DEGENERATED_LIMIT, "sanity"); 147 _heuristics->record_allocation_failure_gc(); 148 _alloc_failure_degenerated++; 149 _degen_points[point]++; 150 } 151 152 void ShenandoahCollectorPolicy::record_degenerated_upgrade_to_full() { 153 _alloc_failure_degenerated_upgrade_to_full++; 154 } 155 156 void ShenandoahCollectorPolicy::record_success_concurrent() { 157 _heuristics->record_success_concurrent(); 158 _success_concurrent_gcs++; 159 } 160 161 void ShenandoahCollectorPolicy::record_success_partial() { 162 _success_partial_gcs++; 163 } 164 165 void ShenandoahCollectorPolicy::record_success_degenerated() { 166 _heuristics->record_success_degenerated(); 167 _success_degenerated_gcs++; 168 } 169 170 void ShenandoahCollectorPolicy::record_success_full() { 171 _heuristics->record_success_full(); 172 _success_full_gcs++; 173 } 174 175 bool ShenandoahCollectorPolicy::should_start_normal_gc() { 176 return _heuristics->should_start_normal_gc(); 177 } 178 179 bool ShenandoahCollectorPolicy::should_degenerate_cycle() { 180 return _heuristics->should_degenerate_cycle(); 181 } 182 183 bool ShenandoahCollectorPolicy::update_refs() { 184 return _heuristics->update_refs(); 185 } 186 187 bool ShenandoahCollectorPolicy::should_start_update_refs() { 188 return _heuristics->should_start_update_refs(); 189 } 190 191 void ShenandoahCollectorPolicy::record_peak_occupancy() { 192 _heuristics->record_peak_occupancy(); 193 } 194 195 void ShenandoahCollectorPolicy::choose_collection_set(ShenandoahCollectionSet* collection_set) { 196 _heuristics->choose_collection_set(collection_set); 197 } 198 199 bool ShenandoahCollectorPolicy::should_process_references() { 200 return _heuristics->should_process_references(); 201 } 202 203 bool ShenandoahCollectorPolicy::should_unload_classes() { 204 return _heuristics->should_unload_classes(); 205 } 206 207 size_t ShenandoahCollectorPolicy::cycle_counter() const { 208 return _cycle_counter; 209 } 210 211 void ShenandoahCollectorPolicy::record_phase_time(ShenandoahPhaseTimings::Phase phase, double secs) { 212 _heuristics->record_phase_time(phase, secs); 213 } 214 215 void ShenandoahCollectorPolicy::record_cycle_start() { 216 _cycle_counter++; 217 _heuristics->record_cycle_start(); 218 } 219 220 void ShenandoahCollectorPolicy::record_cycle_end() { 221 _heuristics->record_cycle_end(); 222 } 223 224 void ShenandoahCollectorPolicy::record_shutdown() { 225 _in_shutdown.set(); 226 } 227 228 bool ShenandoahCollectorPolicy::is_at_shutdown() { 229 return _in_shutdown.is_set(); 230 } 231 232 void ShenandoahCollectorPolicy::print_gc_stats(outputStream* out) const { 233 out->print_cr("Under allocation pressure, concurrent cycles may cancel, and either continue cycle"); 234 out->print_cr("under stop-the-world pause or result in stop-the-world Full GC. Increase heap size,"); 235 out->print_cr("tune GC heuristics, set more aggressive pacing delay, or lower allocation rate"); 236 out->print_cr("to avoid Degenerated and Full GC cycles."); 237 out->cr(); 238 239 out->print_cr(SIZE_FORMAT_W(5) " successful partial concurrent GCs", _success_partial_gcs); 240 out->cr(); 241 242 out->print_cr(SIZE_FORMAT_W(5) " successful concurrent GCs", _success_concurrent_gcs); 243 out->print_cr(" " SIZE_FORMAT_W(5) " invoked explicitly", _explicit_concurrent); 244 out->cr(); 245 246 out->print_cr(SIZE_FORMAT_W(5) " Degenerated GCs", _success_degenerated_gcs); 247 out->print_cr(" " SIZE_FORMAT_W(5) " caused by allocation failure", _alloc_failure_degenerated); 248 for (int c = 0; c < ShenandoahHeap::_DEGENERATED_LIMIT; c++) { 249 if (_degen_points[c] > 0) { 250 const char* desc = ShenandoahHeap::degen_point_to_string((ShenandoahHeap::ShenandoahDegenPoint)c); 251 out->print_cr(" " SIZE_FORMAT_W(5) " happened at %s", _degen_points[c], desc); 252 } 253 } 254 out->print_cr(" " SIZE_FORMAT_W(5) " upgraded to Full GC", _alloc_failure_degenerated_upgrade_to_full); 255 out->cr(); 256 257 out->print_cr(SIZE_FORMAT_W(5) " Full GCs", _success_full_gcs + _alloc_failure_degenerated_upgrade_to_full); 258 out->print_cr(" " SIZE_FORMAT_W(5) " invoked explicitly", _explicit_full); 259 out->print_cr(" " SIZE_FORMAT_W(5) " caused by allocation failure", _alloc_failure_full); 260 out->print_cr(" " SIZE_FORMAT_W(5) " upgraded from Degenerated GC", _alloc_failure_degenerated_upgrade_to_full); 261 }