aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2017-09-25 14:58:13 -0400
committerRuss Cox <rsc@golang.org>2017-10-25 20:23:11 +0000
commitebfcdef90174ea86b2952abec511c0be96b05099 (patch)
treef1aef34b367a97037dad492416c1074077354deb
parent0ab99b396df9fc45c5cf1ac412da4f1848c3462c (diff)
downloadgo-ebfcdef90174ea86b2952abec511c0be96b05099.tar.gz
go-ebfcdef90174ea86b2952abec511c0be96b05099.zip
[release-branch.go1.9] runtime: make runtime.GC() trigger GC even if GOGC=off
Currently, the priority of checks in (gcTrigger).test() puts the gcpercent<0 test above gcTriggerCycle, which is used for runtime.GC(). This is an unintentional change from 1.8 and before, where runtime.GC() triggered a GC even if GOGC=off. Fix this by rearranging the priority so the gcTriggerCycle test executes even if gcpercent < 0. Fixes #22023. Change-Id: I109328d7b643b6824eb9d79061a9e775f0149575 Reviewed-on: https://go-review.googlesource.com/65994 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org> Reviewed-on: https://go-review.googlesource.com/70979 Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Austin Clements <austin@google.com>
-rw-r--r--src/runtime/gc_test.go16
-rw-r--r--src/runtime/mgc.go5
2 files changed, 20 insertions, 1 deletions
diff --git a/src/runtime/gc_test.go b/src/runtime/gc_test.go
index 25dc869caa..0620f2d61e 100644
--- a/src/runtime/gc_test.go
+++ b/src/runtime/gc_test.go
@@ -499,3 +499,19 @@ func BenchmarkReadMemStats(b *testing.B) {
hugeSink = nil
}
+
+func TestUserForcedGC(t *testing.T) {
+ // Test that runtime.GC() triggers a GC even if GOGC=off.
+ defer debug.SetGCPercent(debug.SetGCPercent(-1))
+
+ var ms1, ms2 runtime.MemStats
+ runtime.ReadMemStats(&ms1)
+ runtime.GC()
+ runtime.ReadMemStats(&ms2)
+ if ms1.NumGC == ms2.NumGC {
+ t.Fatalf("runtime.GC() did not trigger GC")
+ }
+ if ms1.NumForcedGC == ms2.NumForcedGC {
+ t.Fatalf("runtime.GC() was not accounted in NumForcedGC")
+ }
+}
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index 111fa781e1..b708720322 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -1158,7 +1158,7 @@ func (t gcTrigger) test() bool {
if t.kind == gcTriggerAlways {
return true
}
- if gcphase != _GCoff || gcpercent < 0 {
+ if gcphase != _GCoff {
return false
}
switch t.kind {
@@ -1169,6 +1169,9 @@ func (t gcTrigger) test() bool {
// own write.
return memstats.heap_live >= memstats.gc_trigger
case gcTriggerTime:
+ if gcpercent < 0 {
+ return false
+ }
lastgc := int64(atomic.Load64(&memstats.last_gc_nanotime))
return lastgc != 0 && t.now-lastgc > forcegcperiod
case gcTriggerCycle: