github.com/bytedance/gopkg@v0.0.0-20240514070511-01b2cbcf35e1/util/gctuner/tuner_test.go (about) 1 // Copyright 2022 ByteDance Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package gctuner 16 17 import ( 18 "runtime" 19 "testing" 20 21 "github.com/stretchr/testify/assert" 22 ) 23 24 var testHeap []byte 25 26 func TestTuner(t *testing.T) { 27 is := assert.New(t) 28 memLimit := uint64(100 * 1024 * 1024) //100 MB 29 threshold := memLimit / 2 30 tn := newTuner(threshold) 31 currentGCPercent := tn.getGCPercent() 32 is.Equal(tn.threshold, threshold) 33 is.Equal(defaultGCPercent, currentGCPercent) 34 35 // wait for tuner set gcPercent to maxGCPercent 36 t.Logf("old gc percent before gc: %d", tn.getGCPercent()) 37 for tn.getGCPercent() != maxGCPercent { 38 runtime.GC() 39 t.Logf("new gc percent after gc: %d", tn.getGCPercent()) 40 } 41 42 // 1/4 threshold 43 testHeap = make([]byte, threshold/4) 44 // wait for tuner set gcPercent to ~= 300 45 t.Logf("old gc percent before gc: %d", tn.getGCPercent()) 46 for tn.getGCPercent() == maxGCPercent { 47 runtime.GC() 48 t.Logf("new gc percent after gc: %d", tn.getGCPercent()) 49 } 50 currentGCPercent = tn.getGCPercent() 51 is.GreaterOrEqual(currentGCPercent, uint32(250)) 52 is.LessOrEqual(currentGCPercent, uint32(300)) 53 54 // 1/2 threshold 55 testHeap = make([]byte, threshold/2) 56 // wait for tuner set gcPercent to ~= 100 57 t.Logf("old gc percent before gc: %d", tn.getGCPercent()) 58 for tn.getGCPercent() == currentGCPercent { 59 runtime.GC() 60 t.Logf("new gc percent after gc: %d", tn.getGCPercent()) 61 } 62 currentGCPercent = tn.getGCPercent() 63 is.GreaterOrEqual(currentGCPercent, uint32(50)) 64 is.LessOrEqual(currentGCPercent, uint32(100)) 65 66 // 3/4 threshold 67 testHeap = make([]byte, threshold/4*3) 68 // wait for tuner set gcPercent to minGCPercent 69 t.Logf("old gc percent before gc: %d", tn.getGCPercent()) 70 for tn.getGCPercent() != minGCPercent { 71 runtime.GC() 72 t.Logf("new gc percent after gc: %d", tn.getGCPercent()) 73 } 74 is.Equal(minGCPercent, tn.getGCPercent()) 75 76 // out of threshold 77 testHeap = make([]byte, threshold+1024) 78 t.Logf("old gc percent before gc: %d", tn.getGCPercent()) 79 runtime.GC() 80 for i := 0; i < 8; i++ { 81 runtime.GC() 82 is.Equal(minGCPercent, tn.getGCPercent()) 83 } 84 85 // no heap 86 testHeap = nil 87 // wait for tuner set gcPercent to maxGCPercent 88 t.Logf("old gc percent before gc: %d", tn.getGCPercent()) 89 for tn.getGCPercent() != maxGCPercent { 90 runtime.GC() 91 t.Logf("new gc percent after gc: %d", tn.getGCPercent()) 92 } 93 } 94 95 func TestCalcGCPercent(t *testing.T) { 96 is := assert.New(t) 97 const gb = 1024 * 1024 * 1024 98 // use default value when invalid params 99 is.Equal(defaultGCPercent, calcGCPercent(0, 0)) 100 is.Equal(defaultGCPercent, calcGCPercent(0, 1)) 101 is.Equal(defaultGCPercent, calcGCPercent(1, 0)) 102 103 is.Equal(maxGCPercent, calcGCPercent(1, 3*gb)) 104 is.Equal(maxGCPercent, calcGCPercent(gb/10, 4*gb)) 105 is.Equal(maxGCPercent, calcGCPercent(gb/2, 4*gb)) 106 is.Equal(uint32(300), calcGCPercent(1*gb, 4*gb)) 107 is.Equal(uint32(166), calcGCPercent(1.5*gb, 4*gb)) 108 is.Equal(uint32(100), calcGCPercent(2*gb, 4*gb)) 109 is.Equal(minGCPercent, calcGCPercent(3*gb, 4*gb)) 110 is.Equal(minGCPercent, calcGCPercent(4*gb, 4*gb)) 111 is.Equal(minGCPercent, calcGCPercent(5*gb, 4*gb)) 112 }