From 0744c21b98e916470c97ff5816630398cf3213c8 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Mon, 25 Sep 2017 14:58:13 -0400 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Rick Hudson --- src/runtime/gc_test.go | 16 ++++++++++++++++ src/runtime/mgc.go | 5 ++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/runtime/gc_test.go b/src/runtime/gc_test.go index 03acc8aaa6..ece5641e1f 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 8118be9e21..48ccfe8df2 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: -- 2.48.1