1 /* 2 * Copyright (c) 2015, 2018, 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 */ 23 24 #include "precompiled.hpp" 25 #include "gc/shared/gcId.hpp" 26 #include "gc/shared/gcLocker.hpp" 27 #include "gc/shared/isGCActiveMark.hpp" 28 #include "gc/shared/vmGCOperations.hpp" 29 #include "gc/z/zCollectedHeap.hpp" 30 #include "gc/z/zDriver.hpp" 31 #include "gc/z/zHeap.inline.hpp" 32 #include "gc/z/zMessagePort.inline.hpp" 33 #include "gc/z/zServiceability.hpp" 34 #include "gc/z/zStat.hpp" 35 #include "logging/log.hpp" 36 #include "runtime/vm_operations.hpp" 37 #include "runtime/vmThread.hpp" 38 39 static const ZStatPhaseCycle ZPhaseCycle("Garbage Collection Cycle"); 40 static const ZStatPhasePause ZPhasePauseMarkStart("Pause Mark Start"); 41 static const ZStatPhaseConcurrent ZPhaseConcurrentMark("Concurrent Mark"); 42 static const ZStatPhaseConcurrent ZPhaseConcurrentMarkContinue("Concurrent Mark Continue"); 43 static const ZStatPhasePause ZPhasePauseMarkEnd("Pause Mark End"); 44 static const ZStatPhaseConcurrent ZPhaseConcurrentProcessNonStrongReferences("Concurrent Process Non-Strong References"); 45 static const ZStatPhaseConcurrent ZPhaseConcurrentResetRelocationSet("Concurrent Reset Relocation Set"); 46 static const ZStatPhaseConcurrent ZPhaseConcurrentDestroyDetachedPages("Concurrent Destroy Detached Pages"); 47 static const ZStatPhaseConcurrent ZPhaseConcurrentSelectRelocationSet("Concurrent Select Relocation Set"); 48 static const ZStatPhaseConcurrent ZPhaseConcurrentPrepareRelocationSet("Concurrent Prepare Relocation Set"); 49 static const ZStatPhasePause ZPhasePauseRelocateStart("Pause Relocate Start"); 50 static const ZStatPhaseConcurrent ZPhaseConcurrentRelocated("Concurrent Relocate"); 51 static const ZStatCriticalPhase ZCriticalPhaseGCLockerStall("GC Locker Stall", false /* verbose */); 52 static const ZStatSampler ZSamplerJavaThreads("System", "Java Threads", ZStatUnitThreads); 53 54 class ZOperationClosure : public StackObj { 55 public: 56 virtual const char* name() const = 0; 57 58 virtual bool needs_inactive_gc_locker() const { 59 // An inactive GC locker is needed in operations where we change the good 60 // mask or move objects. Changing the good mask will invalidate all oops, 61 // which makes it conceptually the same thing as moving all objects. 62 return false; 63 } 64 65 virtual bool do_operation() = 0; 66 }; 67 68 class VM_ZOperation : public VM_Operation { 69 private: 70 ZOperationClosure* _cl; 71 uint _gc_id; 72 bool _gc_locked; 73 bool _success; 74 75 public: 76 VM_ZOperation(ZOperationClosure* cl) : 77 _cl(cl), 78 _gc_id(GCId::current()), 79 _gc_locked(false), 80 _success(false) {} 81 82 virtual VMOp_Type type() const { 83 return VMOp_ZOperation; 84 } 85 86 virtual const char* name() const { 87 return _cl->name(); 88 } 89 90 virtual bool doit_prologue() { 91 Heap_lock->lock(); 92 return true; 93 } 94 95 virtual void doit() { 96 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint"); 97 98 ZStatSample(ZSamplerJavaThreads, Threads::number_of_threads()); 99 100 // JVMTI support 101 SvcGCMarker sgcm(SvcGCMarker::CONCURRENT); 102 103 // Setup GC id 104 GCIdMark gcid(_gc_id); 105 106 if (_cl->needs_inactive_gc_locker() && GCLocker::check_active_before_gc()) { 107 // GC locker is active, bail out 108 _gc_locked = true; 109 } else { 110 // Execute operation 111 IsGCActiveMark mark; 112 _success = _cl->do_operation(); 113 } 114 } 115 116 virtual void doit_epilogue() { 117 Heap_lock->unlock(); 118 } 119 120 bool gc_locked() { 121 return _gc_locked; 122 } 123 124 bool success() const { 125 return _success; 126 } 127 }; 128 129 static bool should_clear_soft_references() { 130 // Clear if one or more allocations have stalled 131 const bool stalled = ZHeap::heap()->is_alloc_stalled(); 132 if (stalled) { 133 // Clear 134 return true; 135 } 136 137 // Clear if implied by the GC cause 138 const GCCause::Cause cause = ZCollectedHeap::heap()->gc_cause(); 139 if (cause == GCCause::_wb_full_gc || 140 cause == GCCause::_metadata_GC_clear_soft_refs) { 141 // Clear 142 return true; 143 } 144 145 // Don't clear 146 return false; 147 } 148 149 static bool should_boost_worker_threads() { 150 // Boost worker threads if one or more allocations have stalled 151 const bool stalled = ZHeap::heap()->is_alloc_stalled(); 152 if (stalled) { 153 // Boost 154 return true; 155 } 156 157 // Boost worker threads if implied by the GC cause 158 const GCCause::Cause cause = ZCollectedHeap::heap()->gc_cause(); 159 if (cause == GCCause::_wb_full_gc || 160 cause == GCCause::_java_lang_system_gc || 161 cause == GCCause::_metadata_GC_clear_soft_refs) { 162 // Boost 163 return true; 164 } 165 166 // Don't boost 167 return false; 168 } 169 170 class ZMarkStartClosure : public ZOperationClosure { 171 public: 172 virtual const char* name() const { 173 return "ZMarkStart"; 174 } 175 176 virtual bool needs_inactive_gc_locker() const { 177 return true; 178 } 179 180 virtual bool do_operation() { 181 ZStatTimer timer(ZPhasePauseMarkStart); 182 ZServiceabilityMarkStartTracer tracer; 183 184 // Set up soft reference policy 185 const bool clear = should_clear_soft_references(); 186 ZHeap::heap()->set_soft_reference_policy(clear); 187 188 // Set up boost mode 189 const bool boost = should_boost_worker_threads(); 190 ZHeap::heap()->set_boost_worker_threads(boost); 191 192 ZCollectedHeap::heap()->increment_total_collections(true /* full */); 193 194 ZHeap::heap()->mark_start(); 195 return true; 196 } 197 }; 198 199 class ZMarkEndClosure : public ZOperationClosure { 200 public: 201 virtual const char* name() const { 202 return "ZMarkEnd"; 203 } 204 205 virtual bool do_operation() { 206 ZStatTimer timer(ZPhasePauseMarkEnd); 207 ZServiceabilityMarkEndTracer tracer; 208 209 return ZHeap::heap()->mark_end(); 210 } 211 }; 212 213 class ZRelocateStartClosure : public ZOperationClosure { 214 public: 215 virtual const char* name() const { 216 return "ZRelocateStart"; 217 } 218 219 virtual bool needs_inactive_gc_locker() const { 220 return true; 221 } 222 223 virtual bool do_operation() { 224 ZStatTimer timer(ZPhasePauseRelocateStart); 225 ZServiceabilityRelocateStartTracer tracer; 226 227 ZHeap::heap()->relocate_start(); 228 return true; 229 } 230 }; 231 232 ZDriver::ZDriver() : 233 _gc_cycle_port(), 234 _gc_locker_port() { 235 set_name("ZDriver"); 236 create_and_start(); 237 } 238 239 bool ZDriver::vm_operation(ZOperationClosure* cl) { 240 for (;;) { 241 VM_ZOperation op(cl); 242 VMThread::execute(&op); 243 if (op.gc_locked()) { 244 // Wait for GC to become unlocked and restart the VM operation 245 ZStatTimer timer(ZCriticalPhaseGCLockerStall); 246 _gc_locker_port.wait(); 247 continue; 248 } 249 250 // Notify VM operation completed 251 _gc_locker_port.ack(); 252 253 return op.success(); 254 } 255 } 256 257 void ZDriver::collect(GCCause::Cause cause) { 258 switch (cause) { 259 case GCCause::_wb_young_gc: 260 case GCCause::_wb_conc_mark: 261 case GCCause::_wb_full_gc: 262 case GCCause::_dcmd_gc_run: 263 case GCCause::_java_lang_system_gc: 264 case GCCause::_full_gc_alot: 265 case GCCause::_scavenge_alot: 266 case GCCause::_jvmti_force_gc: 267 case GCCause::_metadata_GC_clear_soft_refs: 268 // Start synchronous GC 269 _gc_cycle_port.send_sync(cause); 270 break; 271 272 case GCCause::_z_timer: 273 case GCCause::_z_warmup: 274 case GCCause::_z_allocation_rate: 275 case GCCause::_z_allocation_stall: 276 case GCCause::_z_proactive: 277 case GCCause::_metadata_GC_threshold: 278 // Start asynchronous GC 279 _gc_cycle_port.send_async(cause); 280 break; 281 282 case GCCause::_gc_locker: 283 // Restart VM operation previously blocked by the GC locker 284 _gc_locker_port.signal(); 285 break; 286 287 default: 288 // Other causes not supported 289 fatal("Unsupported GC cause (%s)", GCCause::to_string(cause)); 290 break; 291 } 292 } 293 294 GCCause::Cause ZDriver::start_gc_cycle() { 295 // Wait for GC request 296 return _gc_cycle_port.receive(); 297 } 298 299 class ZDriverCycleScope : public StackObj { 300 private: 301 GCIdMark _gc_id; 302 GCCauseSetter _gc_cause_setter; 303 ZStatTimer _timer; 304 305 public: 306 ZDriverCycleScope(GCCause::Cause cause) : 307 _gc_id(), 308 _gc_cause_setter(ZCollectedHeap::heap(), cause), 309 _timer(ZPhaseCycle) { 310 // Update statistics 311 ZStatCycle::at_start(); 312 } 313 314 ~ZDriverCycleScope() { 315 // Calculate boost factor 316 const double boost_factor = (double)ZHeap::heap()->nconcurrent_worker_threads() / 317 (double)ZHeap::heap()->nconcurrent_no_boost_worker_threads(); 318 319 // Update statistics 320 ZStatCycle::at_end(boost_factor); 321 322 // Update data used by soft reference policy 323 Universe::update_heap_info_at_gc(); 324 } 325 }; 326 327 void ZDriver::run_gc_cycle(GCCause::Cause cause) { 328 ZDriverCycleScope scope(cause); 329 330 // Phase 1: Pause Mark Start 331 { 332 ZMarkStartClosure cl; 333 vm_operation(&cl); 334 } 335 336 // Phase 2: Concurrent Mark 337 { 338 ZStatTimer timer(ZPhaseConcurrentMark); 339 ZHeap::heap()->mark(true /* initial */); 340 } 341 342 // Phase 3: Pause Mark End 343 { 344 ZMarkEndClosure cl; 345 while (!vm_operation(&cl)) { 346 // Phase 3.5: Concurrent Mark Continue 347 ZStatTimer timer(ZPhaseConcurrentMarkContinue); 348 ZHeap::heap()->mark(false /* initial */); 349 } 350 } 351 352 // Phase 4: Concurrent Process Non-Strong References 353 { 354 ZStatTimer timer(ZPhaseConcurrentProcessNonStrongReferences); 355 ZHeap::heap()->process_non_strong_references(); 356 } 357 358 // Phase 5: Concurrent Reset Relocation Set 359 { 360 ZStatTimer timer(ZPhaseConcurrentResetRelocationSet); 361 ZHeap::heap()->reset_relocation_set(); 362 } 363 364 // Phase 6: Concurrent Destroy Detached Pages 365 { 366 ZStatTimer timer(ZPhaseConcurrentDestroyDetachedPages); 367 ZHeap::heap()->destroy_detached_pages(); 368 } 369 370 // Phase 7: Concurrent Select Relocation Set 371 { 372 ZStatTimer timer(ZPhaseConcurrentSelectRelocationSet); 373 ZHeap::heap()->select_relocation_set(); 374 } 375 376 // Phase 8: Concurrent Prepare Relocation Set 377 { 378 ZStatTimer timer(ZPhaseConcurrentPrepareRelocationSet); 379 ZHeap::heap()->prepare_relocation_set(); 380 } 381 382 // Phase 9: Pause Relocate Start 383 { 384 ZRelocateStartClosure cl; 385 vm_operation(&cl); 386 } 387 388 // Phase 10: Concurrent Relocate 389 { 390 ZStatTimer timer(ZPhaseConcurrentRelocated); 391 ZHeap::heap()->relocate(); 392 } 393 } 394 395 void ZDriver::end_gc_cycle() { 396 // Notify GC cycle completed 397 _gc_cycle_port.ack(); 398 399 // Check for out of memory condition 400 ZHeap::heap()->check_out_of_memory(); 401 } 402 403 void ZDriver::run_service() { 404 // Main loop 405 while (!should_terminate()) { 406 const GCCause::Cause cause = start_gc_cycle(); 407 if (cause != GCCause::_no_gc) { 408 run_gc_cycle(cause); 409 end_gc_cycle(); 410 } 411 } 412 } 413 414 void ZDriver::stop_service() { 415 _gc_cycle_port.send_async(GCCause::_no_gc); 416 }