mirror of
https://github.com/golang/go
synced 2024-11-22 20:14:40 -07:00
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 <mknyszek@google.com> Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
parent
728e3dc6f9
commit
2d4ba2601b
@ -153,6 +153,7 @@ func gcinit() {
|
|||||||
if unsafe.Sizeof(workbuf{}) != _WorkbufSize {
|
if unsafe.Sizeof(workbuf{}) != _WorkbufSize {
|
||||||
throw("size of Workbuf is suboptimal")
|
throw("size of Workbuf is suboptimal")
|
||||||
}
|
}
|
||||||
|
gcController.heapMinimum = defaultHeapMinimum
|
||||||
|
|
||||||
// No sweep on the first cycle.
|
// No sweep on the first cycle.
|
||||||
mheap_.sweepDrained = 1
|
mheap_.sweepDrained = 1
|
||||||
@ -163,7 +164,7 @@ func gcinit() {
|
|||||||
// Fake a heapMarked value so it looks like a trigger at
|
// Fake a heapMarked value so it looks like a trigger at
|
||||||
// heapMinimum is the appropriate growth from heapMarked.
|
// heapMinimum is the appropriate growth from heapMarked.
|
||||||
// This will go into computing the initial GC goal.
|
// 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
|
// Set gcPercent from the environment. This will also compute
|
||||||
// and set the GC trigger and goal.
|
// and set the GC trigger and goal.
|
||||||
@ -557,7 +558,7 @@ func (t gcTrigger) test() bool {
|
|||||||
// own write.
|
// own write.
|
||||||
return gcController.heapLive >= gcController.trigger
|
return gcController.heapLive >= gcController.trigger
|
||||||
case gcTriggerTime:
|
case gcTriggerTime:
|
||||||
if gcPercent < 0 {
|
if gcController.gcPercent < 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
lastgc := int64(atomic.Load64(&memstats.last_gc_nanotime))
|
lastgc := int64(atomic.Load64(&memstats.last_gc_nanotime))
|
||||||
|
@ -49,25 +49,6 @@ const (
|
|||||||
defaultHeapMinimum = 4 << 20
|
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() {
|
func init() {
|
||||||
if offset := unsafe.Offsetof(gcController.heapLive); offset%8 != 0 {
|
if offset := unsafe.Offsetof(gcController.heapLive); offset%8 != 0 {
|
||||||
println(offset)
|
println(offset)
|
||||||
@ -91,6 +72,25 @@ func init() {
|
|||||||
var gcController gcControllerState
|
var gcController gcControllerState
|
||||||
|
|
||||||
type gcControllerState struct {
|
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.
|
// triggerRatio is the heap growth ratio that triggers marking.
|
||||||
//
|
//
|
||||||
// E.g., if this is 0.6, then GC should start when the live
|
// 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
|
// is when assists are enabled and the necessary statistics are
|
||||||
// available).
|
// available).
|
||||||
func (c *gcControllerState) revise() {
|
func (c *gcControllerState) revise() {
|
||||||
gcPercent := gcPercent
|
gcPercent := c.gcPercent
|
||||||
if gcPercent < 0 {
|
if gcPercent < 0 {
|
||||||
// If GC is disabled but we're running a forced GC,
|
// If GC is disabled but we're running a forced GC,
|
||||||
// act like GOGC is huge for the below calculations.
|
// 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
|
// has grown by GOGC/100 over the heap marked by the last
|
||||||
// cycle.
|
// cycle.
|
||||||
goal := ^uint64(0)
|
goal := ^uint64(0)
|
||||||
if gcPercent >= 0 {
|
if c.gcPercent >= 0 {
|
||||||
goal = c.heapMarked + c.heapMarked*uint64(gcPercent)/100
|
goal = c.heapMarked + c.heapMarked*uint64(c.gcPercent)/100
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the trigger ratio, capped to reasonable bounds.
|
// Set the trigger ratio, capped to reasonable bounds.
|
||||||
if gcPercent >= 0 {
|
if c.gcPercent >= 0 {
|
||||||
scalingFactor := float64(gcPercent) / 100
|
scalingFactor := float64(c.gcPercent) / 100
|
||||||
// Ensure there's always a little margin so that the
|
// Ensure there's always a little margin so that the
|
||||||
// mutator assist ratio isn't infinity.
|
// mutator assist ratio isn't infinity.
|
||||||
maxTriggerRatio := 0.95 * scalingFactor
|
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
|
// We trigger the next GC cycle when the allocated heap has
|
||||||
// grown by the trigger ratio over the marked heap size.
|
// grown by the trigger ratio over the marked heap size.
|
||||||
trigger := ^uint64(0)
|
trigger := ^uint64(0)
|
||||||
if gcPercent >= 0 {
|
if c.gcPercent >= 0 {
|
||||||
trigger = uint64(float64(c.heapMarked) * (1 + triggerRatio))
|
trigger = uint64(float64(c.heapMarked) * (1 + triggerRatio))
|
||||||
// Don't trigger below the minimum heap size.
|
// Don't trigger below the minimum heap size.
|
||||||
minTrigger := heapMinimum
|
minTrigger := c.heapMinimum
|
||||||
if !isSweepDone() {
|
if !isSweepDone() {
|
||||||
// Concurrent sweep happens in the heap growth
|
// Concurrent sweep happens in the heap growth
|
||||||
// from gcController.heapLive to trigger, so ensure
|
// 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.
|
// Run on the system stack since we grab the heap lock.
|
||||||
systemstack(func() {
|
systemstack(func() {
|
||||||
lock(&mheap_.lock)
|
lock(&mheap_.lock)
|
||||||
out = gcPercent
|
out = gcController.gcPercent
|
||||||
if in < 0 {
|
if in < 0 {
|
||||||
in = -1
|
in = -1
|
||||||
}
|
}
|
||||||
gcPercent = in
|
gcController.gcPercent = in
|
||||||
heapMinimum = defaultHeapMinimum * uint64(gcPercent) / 100
|
gcController.heapMinimum = defaultHeapMinimum * uint64(gcController.gcPercent) / 100
|
||||||
// Update pacing in response to gcPercent change.
|
// Update pacing in response to gcPercent change.
|
||||||
gcController.commit(gcController.triggerRatio)
|
gcController.commit(gcController.triggerRatio)
|
||||||
unlock(&mheap_.lock)
|
unlock(&mheap_.lock)
|
||||||
|
Loading…
Reference in New Issue
Block a user