]> Cypherpunks repositories - gostls13.git/commitdiff
runtime/debug: don't trigger a GC on SetGCPercent
authorAustin Clements <austin@google.com>
Tue, 4 Apr 2017 17:26:28 +0000 (13:26 -0400)
committerAustin Clements <austin@google.com>
Fri, 21 Apr 2017 17:42:02 +0000 (17:42 +0000)
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>
src/runtime/debug/garbage.go
src/runtime/debug/garbage_test.go
src/runtime/mgc.go

index 27adc70fd3c0f8c730714bbcd675a9a2da5df569..785e9d4598eac673dd4c6b32b28db7da6f1d73e8 100644 (file)
@@ -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
index 37417aca2c16a908b9dd6d22bebfeeaf72e63e4f..acc781ebdc7c2ac16e6e76ea3d785587b80322a5 100644 (file)
@@ -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 {
index 8ec062af18f6dc100a5f96c3ebd0937f3850b810..5dc417038ab5cd8b76bf70b7af1fb9117a5373b4 100644 (file)
@@ -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
 }