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  }