mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00:00
runtime: update big mgc.go comment
The comment describing the overall GC algorithm at the top of mgc.go has gotten woefully out-of-date (and was possibly never correct/complete). Update it to reflect the current workings of the GC and the set of phases that we now divide it into. Change-Id: I02143c0ebefe9d4cd7753349dab8045f0973bf95 Reviewed-on: https://go-review.googlesource.com/34711 Reviewed-by: Rick Hudson <rlh@golang.org>
This commit is contained in:
parent
cb91dccd86
commit
618c291544
1 changed files with 66 additions and 63 deletions
|
@ -2,9 +2,6 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// TODO(rsc): The code having to do with the heap bitmap needs very serious cleanup.
|
||||
// It has gotten completely out of control.
|
||||
|
||||
// Garbage collector (GC).
|
||||
//
|
||||
// The GC runs concurrently with mutator threads, is type accurate (aka precise), allows multiple
|
||||
|
@ -24,67 +21,73 @@
|
|||
// Hudson, R., and Moss, J.E.B. Copying Garbage Collection without stopping the world.
|
||||
// Concurrency and Computation: Practice and Experience 15(3-5), 2003.
|
||||
//
|
||||
// TODO(austin): The rest of this comment is woefully out of date and
|
||||
// needs to be rewritten. There is no distinct scan phase any more and
|
||||
// we allocate black during GC.
|
||||
// 1. GC performs sweep termination.
|
||||
//
|
||||
// 0. Set phase = GCscan from GCoff.
|
||||
// 1. Wait for all P's to acknowledge phase change.
|
||||
// At this point all goroutines have passed through a GC safepoint and
|
||||
// know we are in the GCscan phase.
|
||||
// 2. GC scans all goroutine stacks, mark and enqueues all encountered pointers
|
||||
// (marking avoids most duplicate enqueuing but races may produce benign duplication).
|
||||
// Preempted goroutines are scanned before P schedules next goroutine.
|
||||
// 3. Set phase = GCmark.
|
||||
// 4. Wait for all P's to acknowledge phase change.
|
||||
// 5. Now write barrier marks and enqueues black, grey, or white to white pointers.
|
||||
// Malloc still allocates white (non-marked) objects.
|
||||
// 6. Meanwhile GC transitively walks the heap marking reachable objects.
|
||||
// 7. When GC finishes marking heap, it preempts P's one-by-one and
|
||||
// retakes partial wbufs (filled by write barrier or during a stack scan of the goroutine
|
||||
// currently scheduled on the P).
|
||||
// 8. Once the GC has exhausted all available marking work it sets phase = marktermination.
|
||||
// 9. Wait for all P's to acknowledge phase change.
|
||||
// 10. Malloc now allocates black objects, so number of unmarked reachable objects
|
||||
// monotonically decreases.
|
||||
// 11. GC preempts P's one-by-one taking partial wbufs and marks all unmarked yet
|
||||
// reachable objects.
|
||||
// 12. When GC completes a full cycle over P's and discovers no new grey
|
||||
// objects, (which means all reachable objects are marked) set phase = GCoff.
|
||||
// 13. Wait for all P's to acknowledge phase change.
|
||||
// 14. Now malloc allocates white (but sweeps spans before use).
|
||||
// Write barrier becomes nop.
|
||||
// 15. GC does background sweeping, see description below.
|
||||
// 16. When sufficient allocation has taken place replay the sequence starting at 0 above,
|
||||
// see discussion of GC rate below.
|
||||
|
||||
// Changing phases.
|
||||
// Phases are changed by setting the gcphase to the next phase and possibly calling ackgcphase.
|
||||
// All phase action must be benign in the presence of a change.
|
||||
// Starting with GCoff
|
||||
// GCoff to GCscan
|
||||
// GSscan scans stacks and globals greying them and never marks an object black.
|
||||
// Once all the P's are aware of the new phase they will scan gs on preemption.
|
||||
// This means that the scanning of preempted gs can't start until all the Ps
|
||||
// have acknowledged.
|
||||
// When a stack is scanned, this phase also installs stack barriers to
|
||||
// track how much of the stack has been active.
|
||||
// This transition enables write barriers because stack barriers
|
||||
// assume that writes to higher frames will be tracked by write
|
||||
// barriers. Technically this only needs write barriers for writes
|
||||
// to stack slots, but we enable write barriers in general.
|
||||
// GCscan to GCmark
|
||||
// In GCmark, work buffers are drained until there are no more
|
||||
// pointers to scan.
|
||||
// No scanning of objects (making them black) can happen until all
|
||||
// Ps have enabled the write barrier, but that already happened in
|
||||
// the transition to GCscan.
|
||||
// GCmark to GCmarktermination
|
||||
// The only change here is that we start allocating black so the Ps must acknowledge
|
||||
// the change before we begin the termination algorithm
|
||||
// GCmarktermination to GSsweep
|
||||
// Object currently on the freelist must be marked black for this to work.
|
||||
// Are things on the free lists black or white? How does the sweep phase work?
|
||||
// a. Stop the world. This causes all Ps to reach a GC safe-point.
|
||||
//
|
||||
// b. Sweep any unswept spans. There will only be unswept spans if
|
||||
// this GC cycle was forced before the expected time.
|
||||
//
|
||||
// 2. GC performs the "mark 1" sub-phase. In this sub-phase, Ps are
|
||||
// allowed to locally cache parts of the work queue.
|
||||
//
|
||||
// a. Prepare for the mark phase by setting gcphase to _GCmark
|
||||
// (from _GCoff), enabling the write barrier, enabling mutator
|
||||
// assists, and enqueueing root mark jobs. No objects may be
|
||||
// scanned until all Ps have enabled the write barrier, which is
|
||||
// accomplished using STW.
|
||||
//
|
||||
// b. Start the world. From this point, GC work is done by mark
|
||||
// workers started by the scheduler and by assists performed as
|
||||
// part of allocation. The write barrier shades both the
|
||||
// overwritten pointer and the new pointer value for any pointer
|
||||
// writes (see mbarrier.go for details). Newly allocated objects
|
||||
// are immediately marked black.
|
||||
//
|
||||
// c. GC performs root marking jobs. This includes scanning all
|
||||
// stacks, shading all globals, and shading any heap pointers in
|
||||
// off-heap runtime data structures. Scanning a stack stops a
|
||||
// goroutine, shades any pointers found on its stack, and then
|
||||
// resumes the goroutine.
|
||||
//
|
||||
// d. GC drains the work queue of grey objects, scanning each grey
|
||||
// object to black and shading all pointers found in the object
|
||||
// (which in turn may add those pointers to the work queue).
|
||||
//
|
||||
// 3. Once the global work queue is empty (but local work queue caches
|
||||
// may still contain work), GC performs the "mark 2" sub-phase.
|
||||
//
|
||||
// a. GC stops all workers, disables local work queue caches,
|
||||
// flushes each P's local work queue cache to the global work queue
|
||||
// cache, and reenables workers.
|
||||
//
|
||||
// b. GC again drains the work queue, as in 2d above.
|
||||
//
|
||||
// 4. Once the work queue is empty, GC performs mark termination.
|
||||
//
|
||||
// a. Stop the world.
|
||||
//
|
||||
// b. Set gcphase to _GCmarktermination, and disable workers and
|
||||
// assists.
|
||||
//
|
||||
// c. Drain any remaining work from the work queue (typically there
|
||||
// will be none).
|
||||
//
|
||||
// d. Perform other housekeeping like flushing mcaches.
|
||||
//
|
||||
// 5. GC performs the sweep phase.
|
||||
//
|
||||
// a. Prepare for the sweep phase by setting gcphase to _GCoff,
|
||||
// setting up sweep state and disabling the write barrier.
|
||||
//
|
||||
// b. Start the world. From this point on, newly allocated objects
|
||||
// are white, and allocating sweeps spans before use if necessary.
|
||||
//
|
||||
// c. GC does concurrent sweeping in the background and in response
|
||||
// to allocation. See description below.
|
||||
//
|
||||
// 6. When sufficient allocation has taken place, replay the sequence
|
||||
// starting with 1 above. See discussion of GC rate below.
|
||||
|
||||
// Concurrent sweep.
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue