@@ -57,16 +57,16 @@ func TestGlobalMemoryTuner(t *testing.T) {
57
57
memory .ServerMemoryLimit .Store (1 << 30 ) // 1GB
58
58
GlobalMemoryLimitTuner .SetPercentage (0.8 ) // 1GB * 80% = 800MB
59
59
GlobalMemoryLimitTuner .UpdateMemoryLimit ()
60
- require .True (t , GlobalMemoryLimitTuner .isTuning .Load ())
60
+ require .True (t , GlobalMemoryLimitTuner .isValidValueSet .Load ())
61
61
defer func () {
62
62
// If test.count > 1, wait tuning finished.
63
63
require .Eventually (t , func () bool {
64
64
//nolint: all_revive
65
- return GlobalMemoryLimitTuner .isTuning .Load ()
65
+ return GlobalMemoryLimitTuner .isValidValueSet .Load ()
66
66
}, 5 * time .Second , 100 * time .Millisecond )
67
67
require .Eventually (t , func () bool {
68
68
//nolint: all_revive
69
- return ! GlobalMemoryLimitTuner .waitingReset .Load ()
69
+ return ! GlobalMemoryLimitTuner .adjustPercentageInProgress .Load ()
70
70
}, 5 * time .Second , 100 * time .Millisecond )
71
71
require .Eventually (t , func () bool {
72
72
//nolint: all_revive
@@ -85,7 +85,7 @@ func TestGlobalMemoryTuner(t *testing.T) {
85
85
runtime .ReadMemStats (r )
86
86
nextGC := r .NextGC
87
87
memoryLimit := GlobalMemoryLimitTuner .calcMemoryLimit (GlobalMemoryLimitTuner .GetPercentage ())
88
- // In golang source, nextGC = memoryLimit - three parts memory.
88
+ // Refer to golang source code , nextGC = memoryLimit - nonHeapMemory - overageMemory - headroom
89
89
require .True (t , nextGC < uint64 (memoryLimit ))
90
90
}
91
91
@@ -94,7 +94,7 @@ func TestGlobalMemoryTuner(t *testing.T) {
94
94
95
95
memory210mb := allocator .alloc (210 << 20 )
96
96
require .Eventually (t , func () bool {
97
- return GlobalMemoryLimitTuner .waitingReset .Load () && gcNum < getNowGCNum ()
97
+ return GlobalMemoryLimitTuner .adjustPercentageInProgress .Load () && gcNum < getNowGCNum ()
98
98
}, 5 * time .Second , 100 * time .Millisecond )
99
99
// Test waiting for reset
100
100
require .Eventually (t , func () bool {
@@ -123,3 +123,97 @@ func TestGlobalMemoryTuner(t *testing.T) {
123
123
allocator .free (memory210mb )
124
124
allocator .free (memory600mb )
125
125
}
126
+
127
+ func TestIssue48741 (t * testing.T ) {
128
+ // Close GOGCTuner
129
+ gogcTuner := EnableGOGCTuner .Load ()
130
+ EnableGOGCTuner .Store (false )
131
+ defer EnableGOGCTuner .Store (gogcTuner )
132
+
133
+ r := & runtime.MemStats {}
134
+ getNowGCNum := func () uint32 {
135
+ runtime .ReadMemStats (r )
136
+ return r .NumGC
137
+ }
138
+ allocator := & mockAllocator {}
139
+ defer allocator .freeAll ()
140
+
141
+ checkIfMemoryLimitIsModified := func () {
142
+ memory .ServerMemoryLimit .Store (1500 << 20 ) // 1.5 GB
143
+
144
+ // Try to trigger GC by 1GB * 80% = 800MB (tidb_server_memory_limit * tidb_server_memory_limit_gc_trigger)
145
+ gcNum := getNowGCNum ()
146
+ memory810mb := allocator .alloc (810 << 20 )
147
+ require .Eventually (t ,
148
+ // Wait for the GC triggered by memory810mb
149
+ func () bool {
150
+ return GlobalMemoryLimitTuner .adjustPercentageInProgress .Load () && gcNum < getNowGCNum ()
151
+ },
152
+ 500 * time .Millisecond , 100 * time .Millisecond )
153
+
154
+ gcNumAfterMemory810mb := getNowGCNum ()
155
+ // After the GC triggered by memory810mb.
156
+ time .Sleep (4500 * time .Millisecond )
157
+ require .Equal (t , debug .SetMemoryLimit (- 1 ), int64 (1500 << 20 * 80 / 100 ))
158
+
159
+ memory700mb := allocator .alloc (200 << 20 )
160
+ time .Sleep (5 * time .Second )
161
+ // The heapInUse is less than 1.5GB * 80% = 1.2GB, so the gc will not be triggered.
162
+ require .Equal (t , gcNumAfterMemory810mb , getNowGCNum ())
163
+
164
+ memory150mb := allocator .alloc (300 << 20 )
165
+ require .Eventually (t ,
166
+ // Wait for the GC triggered by memory810mb
167
+ func () bool {
168
+ return GlobalMemoryLimitTuner .adjustPercentageInProgress .Load () && gcNumAfterMemory810mb < getNowGCNum ()
169
+ },
170
+ 5 * time .Second , 100 * time .Millisecond )
171
+
172
+ time .Sleep (4500 * time .Millisecond )
173
+ require .Equal (t , debug .SetMemoryLimit (- 1 ), int64 (1500 << 20 * 110 / 100 ))
174
+
175
+ allocator .free (memory810mb )
176
+ allocator .free (memory700mb )
177
+ allocator .free (memory150mb )
178
+ }
179
+
180
+ checkIfMemoryLimitNotModified := func () {
181
+ // Try to trigger GC by 1GB * 80% = 800MB (tidb_server_memory_limit * tidb_server_memory_limit_gc_trigger)
182
+ gcNum := getNowGCNum ()
183
+ memory810mb := allocator .alloc (810 << 20 )
184
+ require .Eventually (t ,
185
+ // Wait for the GC triggered by memory810mb
186
+ func () bool {
187
+ return GlobalMemoryLimitTuner .adjustPercentageInProgress .Load () && gcNum < getNowGCNum ()
188
+ },
189
+ 500 * time .Millisecond , 100 * time .Millisecond )
190
+
191
+ gcNumAfterMemory810mb := getNowGCNum ()
192
+ // After the GC triggered by memory810mb.
193
+ time .Sleep (4500 * time .Millisecond )
194
+ // During the process of adjusting the percentage, the memory limit will be set to 1GB * 110% = 1.1GB.
195
+ require .Equal (t , debug .SetMemoryLimit (- 1 ), int64 (1 << 30 * 110 / 100 ))
196
+
197
+ require .Eventually (t ,
198
+ // The GC will be trigged immediately after memoryLimit is set back to 1GB * 80% = 800MB.
199
+ func () bool {
200
+ return GlobalMemoryLimitTuner .adjustPercentageInProgress .Load () && gcNumAfterMemory810mb < getNowGCNum ()
201
+ },
202
+ 2 * time .Second , 100 * time .Millisecond )
203
+
204
+ allocator .free (memory810mb )
205
+ }
206
+
207
+ require .NoError (t , failpoint .Enable ("github.com/pingcap/tidb/util/gctuner/mockUpdateGlobalVarDuringAdjustPercentage" , "return(true)" ))
208
+ defer func () {
209
+ require .NoError (t , failpoint .Disable ("github.com/pingcap/tidb/util/gctuner/mockUpdateGlobalVarDuringAdjustPercentage" ))
210
+ }()
211
+
212
+ memory .ServerMemoryLimit .Store (1 << 30 ) // 1GB
213
+ GlobalMemoryLimitTuner .SetPercentage (0.8 ) // 1GB * 80% = 800MB
214
+ GlobalMemoryLimitTuner .UpdateMemoryLimit ()
215
+ require .Equal (t , debug .SetMemoryLimit (- 1 ), int64 (1 << 30 * 80 / 100 ))
216
+
217
+ checkIfMemoryLimitNotModified ()
218
+ checkIfMemoryLimitIsModified ()
219
+ }
0 commit comments