aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2017-04-04 13:26:28 -0400
committerAustin Clements <austin@google.com>2017-04-21 17:42:02 +0000
commit227fff2ea4f21ec357eebe27324cc04b7c9919c7 (patch)
treebdfc85c7e04b189e584599665ca113d361056413 /src/runtime
parentd9308cbb516fc581ff7c7f77781d51604be44da6 (diff)
downloadgo-227fff2ea4f21ec357eebe27324cc04b7c9919c7.tar.xz
runtime/debug: don't trigger a GC on SetGCPercent
Currently SetGCPercent forces a GC in order to recompute GC pacing. Since we can now recompute pacing on the fly using gcSetTriggerRatio, change SetGCPercent (really runtime.setGCPercent) to go through gcSetTriggerRatio and not trigger a GC. Fixes #19076. Change-Id: Ib30d7ab1bb3b55219535b9f238108f3d45a1b522 Reviewed-on: https://go-review.googlesource.com/39835 Run-TryBot: Austin Clements <austin@google.com> Reviewed-by: Rick Hudson <rlh@golang.org>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/debug/garbage.go6
-rw-r--r--src/runtime/debug/garbage_test.go2
-rw-r--r--src/runtime/mgc.go31
3 files changed, 17 insertions, 22 deletions
diff --git a/src/runtime/debug/garbage.go b/src/runtime/debug/garbage.go
index 27adc70fd3..785e9d4598 100644
--- a/src/runtime/debug/garbage.go
+++ b/src/runtime/debug/garbage.go
@@ -89,11 +89,7 @@ func ReadGCStats(stats *GCStats) {
// at startup, or 100 if the variable is not set.
// A negative percentage disables garbage collection.
func SetGCPercent(percent int) int {
- old := setGCPercent(int32(percent))
- if percent >= 0 {
- runtime.GC()
- }
- return int(old)
+ return int(setGCPercent(int32(percent)))
}
// FreeOSMemory forces a garbage collection followed by an
diff --git a/src/runtime/debug/garbage_test.go b/src/runtime/debug/garbage_test.go
index 37417aca2c..acc781ebdc 100644
--- a/src/runtime/debug/garbage_test.go
+++ b/src/runtime/debug/garbage_test.go
@@ -160,6 +160,8 @@ func TestSetGCPercent(t *testing.T) {
runtime.ReadMemStats(&ms)
ngc1 := ms.NumGC
SetGCPercent(10)
+ // It may require an allocation to actually force the GC.
+ setGCPercentSink = make([]byte, 1<<20)
runtime.ReadMemStats(&ms)
ngc2 := ms.NumGC
if ngc1 == ngc2 {
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index 8ec062af18..5dc417038a 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -178,20 +178,21 @@ func gcinit() {
throw("size of Workbuf is suboptimal")
}
- _ = setGCPercent(readgogc())
+ // No sweep on the first cycle.
+ mheap_.sweepdone = 1
// Set a reasonable initial GC trigger.
memstats.triggerRatio = 7 / 8.0
- memstats.gc_trigger = heapminimum
- // Compute the goal heap size based on the trigger:
- // trigger = marked * (1 + triggerRatio)
- // marked = trigger / (1 + triggerRatio)
- // goal = marked * (1 + GOGC/100)
- // = trigger / (1 + triggerRatio) * (1 + GOGC/100)
- memstats.next_gc = uint64(float64(memstats.gc_trigger) / (1 + memstats.triggerRatio) * (1 + float64(gcpercent)/100))
- if gcpercent < 0 {
- memstats.next_gc = ^uint64(0)
- }
+
+ // Fake a heap_marked value so it looks like a trigger at
+ // heapminimum is the appropriate growth from heap_marked.
+ // This will go into computing the initial GC goal.
+ memstats.heap_marked = uint64(float64(heapminimum) / (1 + memstats.triggerRatio))
+
+ // Set gcpercent from the environment. This will also compute
+ // and set the GC trigger and goal.
+ _ = setGCPercent(readgogc())
+
work.startSema = 1
work.markDoneSema = 1
}
@@ -226,12 +227,8 @@ func setGCPercent(in int32) (out int32) {
}
gcpercent = in
heapminimum = defaultHeapMinimum * uint64(gcpercent) / 100
- if memstats.triggerRatio > float64(gcpercent)/100 {
- memstats.triggerRatio = float64(gcpercent) / 100
- }
- // This is either in gcinit or followed by a STW GC, both of
- // which will reset other stats like memstats.gc_trigger and
- // memstats.next_gc to appropriate values.
+ // Update pacing in response to gcpercent change.
+ gcSetTriggerRatio(memstats.triggerRatio)
unlock(&mheap_.lock)
return out
}