Skip to content

Commit

Permalink
gogctuner: support Max/Min GOGC (#39109)
Browse files Browse the repository at this point in the history
close #39110
  • Loading branch information
hawkingrei authored Nov 14, 2022
1 parent efa7010 commit 4dd00bc
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 24 deletions.
39 changes: 27 additions & 12 deletions util/gctuner/tuner.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,37 @@ import (
"github.com/pingcap/tidb/util"
)

var (
maxGCPercent atomic.Uint32
minGCPercent atomic.Uint32

// EnableGOGCTuner is to control whether enable the GOGC tuner.
EnableGOGCTuner atomic.Bool

defaultGCPercent uint32 = 100
)

const (
// MaxGCPercent is the default max cost of memory.
MaxGCPercent uint32 = 500
// MinGCPercent is the default min cost of memory.
MinGCPercent uint32 = 100
defaultMaxGCPercent uint32 = 500
defaultMinGCPercent uint32 = 100
)

var defaultGCPercent uint32 = 100
// SetMaxGCPercent sets the max cost of memory.
func SetMaxGCPercent(percent uint32) {
maxGCPercent.Store(percent)
}

// EnableGOGCTuner is to control whether enable the GOGC tuner.
var EnableGOGCTuner atomic.Bool
// SetMinGCPercent sets the max cost of memory.
func SetMinGCPercent(percent uint32) {
minGCPercent.Store(percent)
}

func init() {
if val, err := strconv.Atoi(os.Getenv("GOGC")); err == nil {
defaultGCPercent = uint32(val)
}
SetMinGCPercent(defaultMinGCPercent)
SetMaxGCPercent(defaultMaxGCPercent)
}

// SetDefaultGOGC is to set the default GOGC value.
Expand Down Expand Up @@ -151,13 +166,13 @@ func calcGCPercent(inuse, threshold uint64) uint32 {
}
// inuse heap larger than threshold, use min percent
if threshold <= inuse {
return MinGCPercent
return minGCPercent.Load()
}
gcPercent := uint32(math.Floor(float64(threshold-inuse) / float64(inuse) * 100))
if gcPercent < MinGCPercent {
return MinGCPercent
} else if gcPercent > MaxGCPercent {
return MaxGCPercent
if gcPercent < minGCPercent.Load() {
return minGCPercent.Load()
} else if gcPercent > maxGCPercent.Load() {
return maxGCPercent.Load()
}
return gcPercent
}
24 changes: 12 additions & 12 deletions util/gctuner/tuner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,40 +37,40 @@ func TestTuner(t *testing.T) {
runtime.GC()
for i := 0; i < 100; i++ {
runtime.GC()
require.Equal(t, MaxGCPercent, tn.getGCPercent())
require.Equal(t, maxGCPercent.Load(), tn.getGCPercent())
}

// 1/4 threshold
testHeap = make([]byte, threshold/4)
for i := 0; i < 100; i++ {
runtime.GC()
require.GreaterOrEqual(t, tn.getGCPercent(), MaxGCPercent/2)
require.LessOrEqual(t, tn.getGCPercent(), MaxGCPercent)
require.GreaterOrEqual(t, tn.getGCPercent(), maxGCPercent.Load()/2)
require.LessOrEqual(t, tn.getGCPercent(), maxGCPercent.Load())
}

// 1/2 threshold
testHeap = make([]byte, threshold/2)
runtime.GC()
for i := 0; i < 100; i++ {
runtime.GC()
require.GreaterOrEqual(t, tn.getGCPercent(), MinGCPercent)
require.LessOrEqual(t, tn.getGCPercent(), MaxGCPercent/2)
require.GreaterOrEqual(t, tn.getGCPercent(), minGCPercent.Load())
require.LessOrEqual(t, tn.getGCPercent(), maxGCPercent.Load()/2)
}

// 3/4 threshold
testHeap = make([]byte, threshold/4*3)
runtime.GC()
for i := 0; i < 100; i++ {
runtime.GC()
require.Equal(t, MinGCPercent, tn.getGCPercent())
require.Equal(t, minGCPercent.Load(), tn.getGCPercent())
}

// out of threshold
testHeap = make([]byte, threshold+1024)
runtime.GC()
for i := 0; i < 100; i++ {
runtime.GC()
require.Equal(t, MinGCPercent, tn.getGCPercent())
require.Equal(t, minGCPercent.Load(), tn.getGCPercent())
}
}

Expand All @@ -81,13 +81,13 @@ func TestCalcGCPercent(t *testing.T) {
require.Equal(t, defaultGCPercent, calcGCPercent(0, 1))
require.Equal(t, defaultGCPercent, calcGCPercent(1, 0))

require.Equal(t, MaxGCPercent, calcGCPercent(1, 3*gb))
require.Equal(t, MaxGCPercent, calcGCPercent(gb/10, 4*gb))
require.Equal(t, MaxGCPercent, calcGCPercent(gb/2, 4*gb))
require.Equal(t, maxGCPercent.Load(), calcGCPercent(1, 3*gb))
require.Equal(t, maxGCPercent.Load(), calcGCPercent(gb/10, 4*gb))
require.Equal(t, maxGCPercent.Load(), calcGCPercent(gb/2, 4*gb))
require.Equal(t, uint32(300), calcGCPercent(1*gb, 4*gb))
require.Equal(t, uint32(166), calcGCPercent(1.5*gb, 4*gb))
require.Equal(t, uint32(100), calcGCPercent(2*gb, 4*gb))
require.Equal(t, uint32(100), calcGCPercent(3*gb, 4*gb))
require.Equal(t, MinGCPercent, calcGCPercent(4*gb, 4*gb))
require.Equal(t, MinGCPercent, calcGCPercent(5*gb, 4*gb))
require.Equal(t, minGCPercent.Load(), calcGCPercent(4*gb, 4*gb))
require.Equal(t, minGCPercent.Load(), calcGCPercent(5*gb, 4*gb))
}

0 comments on commit 4dd00bc

Please sign in to comment.