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