From 2d4ba2601b91e2e69712861c654e4ddaf4355f49 Mon Sep 17 00:00:00 2001 From: Michael Anthony Knyszek Date: Thu, 1 Apr 2021 17:56:32 +0000 Subject: [PATCH] runtime: move gcPercent and heapMinimum into gcControllerState These variables are core to the pacer, and will be need to be non-global for testing later. Partially generated via rf ' ex . { gcPercent -> gcController.gcPercent heapMinimum -> gcController.heapMinimum } ' The only exception to this generation is usage of these variables in gcControllerState methods. For #44167. Change-Id: I8b620b3061114f3a3c4b65006f715fd977b180a8 Reviewed-on: https://go-review.googlesource.com/c/go/+/306600 Trust: Michael Knyszek Run-TryBot: Michael Knyszek TryBot-Result: Go Bot Reviewed-by: Michael Pratt --- src/runtime/mgc.go | 5 ++-- src/runtime/mgcpacer.go | 58 ++++++++++++++++++++--------------------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go index f523d42812..b0d46d0060 100644 --- a/src/runtime/mgc.go +++ b/src/runtime/mgc.go @@ -153,6 +153,7 @@ func gcinit() { if unsafe.Sizeof(workbuf{}) != _WorkbufSize { throw("size of Workbuf is suboptimal") } + gcController.heapMinimum = defaultHeapMinimum // No sweep on the first cycle. mheap_.sweepDrained = 1 @@ -163,7 +164,7 @@ func gcinit() { // Fake a heapMarked value so it looks like a trigger at // heapMinimum is the appropriate growth from heapMarked. // This will go into computing the initial GC goal. - gcController.heapMarked = uint64(float64(heapMinimum) / (1 + gcController.triggerRatio)) + gcController.heapMarked = uint64(float64(gcController.heapMinimum) / (1 + gcController.triggerRatio)) // Set gcPercent from the environment. This will also compute // and set the GC trigger and goal. @@ -557,7 +558,7 @@ func (t gcTrigger) test() bool { // own write. return gcController.heapLive >= gcController.trigger case gcTriggerTime: - if gcPercent < 0 { + if gcController.gcPercent < 0 { return false } lastgc := int64(atomic.Load64(&memstats.last_gc_nanotime)) diff --git a/src/runtime/mgcpacer.go b/src/runtime/mgcpacer.go index 51cb3bb1b9..e594dbdc06 100644 --- a/src/runtime/mgcpacer.go +++ b/src/runtime/mgcpacer.go @@ -49,25 +49,6 @@ const ( defaultHeapMinimum = 4 << 20 ) -var ( - // heapMinimum is the minimum heap size at which to trigger GC. - // For small heaps, this overrides the usual GOGC*live set rule. - // - // When there is a very small live set but a lot of allocation, simply - // collecting when the heap reaches GOGC*live results in many GC - // cycles and high total per-GC overhead. This minimum amortizes this - // per-GC overhead while keeping the heap reasonably small. - // - // During initialization this is set to 4MB*GOGC/100. In the case of - // GOGC==0, this will set heapMinimum to 0, resulting in constant - // collection even when the heap size is small, which is useful for - // debugging. - heapMinimum uint64 = defaultHeapMinimum - - // Initialized from $GOGC. GOGC=off means no GC. - gcPercent int32 -) - func init() { if offset := unsafe.Offsetof(gcController.heapLive); offset%8 != 0 { println(offset) @@ -91,6 +72,25 @@ func init() { var gcController gcControllerState type gcControllerState struct { + // Initialized from $GOGC. GOGC=off means no GC. + gcPercent int32 + + _ uint32 // padding so following 64-bit values are 8-byte aligned + + // heapMinimum is the minimum heap size at which to trigger GC. + // For small heaps, this overrides the usual GOGC*live set rule. + // + // When there is a very small live set but a lot of allocation, simply + // collecting when the heap reaches GOGC*live results in many GC + // cycles and high total per-GC overhead. This minimum amortizes this + // per-GC overhead while keeping the heap reasonably small. + // + // During initialization this is set to 4MB*GOGC/100. In the case of + // GOGC==0, this will set heapMinimum to 0, resulting in constant + // collection even when the heap size is small, which is useful for + // debugging. + heapMinimum uint64 + // triggerRatio is the heap growth ratio that triggers marking. // // E.g., if this is 0.6, then GC should start when the live @@ -337,7 +337,7 @@ func (c *gcControllerState) startCycle() { // is when assists are enabled and the necessary statistics are // available). func (c *gcControllerState) revise() { - gcPercent := gcPercent + gcPercent := c.gcPercent if gcPercent < 0 { // If GC is disabled but we're running a forced GC, // act like GOGC is huge for the below calculations. @@ -624,13 +624,13 @@ func (c *gcControllerState) commit(triggerRatio float64) { // has grown by GOGC/100 over the heap marked by the last // cycle. goal := ^uint64(0) - if gcPercent >= 0 { - goal = c.heapMarked + c.heapMarked*uint64(gcPercent)/100 + if c.gcPercent >= 0 { + goal = c.heapMarked + c.heapMarked*uint64(c.gcPercent)/100 } // Set the trigger ratio, capped to reasonable bounds. - if gcPercent >= 0 { - scalingFactor := float64(gcPercent) / 100 + if c.gcPercent >= 0 { + scalingFactor := float64(c.gcPercent) / 100 // Ensure there's always a little margin so that the // mutator assist ratio isn't infinity. maxTriggerRatio := 0.95 * scalingFactor @@ -670,10 +670,10 @@ func (c *gcControllerState) commit(triggerRatio float64) { // We trigger the next GC cycle when the allocated heap has // grown by the trigger ratio over the marked heap size. trigger := ^uint64(0) - if gcPercent >= 0 { + if c.gcPercent >= 0 { trigger = uint64(float64(c.heapMarked) * (1 + triggerRatio)) // Don't trigger below the minimum heap size. - minTrigger := heapMinimum + minTrigger := c.heapMinimum if !isSweepDone() { // Concurrent sweep happens in the heap growth // from gcController.heapLive to trigger, so ensure @@ -774,12 +774,12 @@ func setGCPercent(in int32) (out int32) { // Run on the system stack since we grab the heap lock. systemstack(func() { lock(&mheap_.lock) - out = gcPercent + out = gcController.gcPercent if in < 0 { in = -1 } - gcPercent = in - heapMinimum = defaultHeapMinimum * uint64(gcPercent) / 100 + gcController.gcPercent = in + gcController.heapMinimum = defaultHeapMinimum * uint64(gcController.gcPercent) / 100 // Update pacing in response to gcPercent change. gcController.commit(gcController.triggerRatio) unlock(&mheap_.lock) -- 2.48.1