@ -23,22 +23,37 @@ import (
|
||||
"github.com/pingcap/tidb/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// MaxGCPercent is the default max cost of memory.
|
||||
MaxGCPercent uint32 = 500
|
||||
// MinGCPercent is the default min cost of memory.
|
||||
MinGCPercent uint32 = 100
|
||||
var (
|
||||
maxGCPercent atomic.Uint32
|
||||
minGCPercent atomic.Uint32
|
||||
|
||||
// EnableGOGCTuner is to control whether enable the GOGC tuner.
|
||||
EnableGOGCTuner atomic.Bool
|
||||
|
||||
defaultGCPercent uint32 = 100
|
||||
)
|
||||
|
||||
var defaultGCPercent uint32 = 100
|
||||
const (
|
||||
defaultMaxGCPercent uint32 = 500
|
||||
defaultMinGCPercent uint32 = 100
|
||||
)
|
||||
|
||||
// EnableGOGCTuner is to control whether enable the GOGC tuner.
|
||||
var EnableGOGCTuner atomic.Bool
|
||||
// SetMaxGCPercent sets the max cost of memory.
|
||||
func SetMaxGCPercent(percent uint32) {
|
||||
maxGCPercent.Store(percent)
|
||||
}
|
||||
|
||||
// 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.
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -37,15 +37,15 @@ 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
|
||||
@ -53,8 +53,8 @@ func TestTuner(t *testing.T) {
|
||||
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
|
||||
@ -62,7 +62,7 @@ func TestTuner(t *testing.T) {
|
||||
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
|
||||
@ -70,7 +70,7 @@ func TestTuner(t *testing.T) {
|
||||
runtime.GC()
|
||||
for i := 0; i < 100; i++ {
|
||||
runtime.GC()
|
||||
require.Equal(t, MinGCPercent, tn.getGCPercent())
|
||||
require.Equal(t, minGCPercent.Load(), tn.getGCPercent())
|
||||
}
|
||||
}
|
||||
|
||||
@ -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))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user