feat: concurrent.Pool 新增 EAC 函数,用于动态调整缓冲区大小。优化超出缓冲区大小警告日志,增加堆栈信息,用于定位高频点

This commit is contained in:
kercylan98 2023-08-21 16:06:44 +08:00
parent 2e0a49d354
commit 64ecd459a1
2 changed files with 50 additions and 4 deletions

View File

@ -2,6 +2,7 @@ package concurrent
import (
"github.com/kercylan98/minotaur/utils/log"
"go.uber.org/zap"
"sync"
)
@ -27,7 +28,20 @@ type Pool[T any] struct {
bufferSize int
generator func() T
releaser func(data T)
warn int
warn int64
}
// EAC 动态调整缓冲区大小,适用于突发场景使用
// - 当 size <= 0 时,不进行调整
// - 当缓冲区大小不足时,会导致大量的新对象生成、销毁,增加 GC 压力。此时应考虑调整缓冲区大小
// - 当缓冲区大小过大时,会导致大量的对象占用内存,增加内存压力。此时应考虑调整缓冲区大小
func (slf *Pool[T]) EAC(size int) {
if size <= 0 {
return
}
slf.mutex.Lock()
slf.bufferSize = size
slf.mutex.Unlock()
}
func (slf *Pool[T]) Get() T {
@ -38,10 +52,10 @@ func (slf *Pool[T]) Get() T {
slf.mutex.Unlock()
return data
}
slf.mutex.Unlock()
slf.warn++
if slf.warn >= 100 {
log.Warn("Pool", log.String("Get", "the number of buffer members is insufficient, consider whether it is due to unreleased or inappropriate buffer size"))
slf.mutex.Unlock()
if slf.warn >= 256 {
log.Warn("Pool", log.String("Get", "the number of buffer members is insufficient, consider whether it is due to unreleased or inappropriate buffer size"), zap.Stack("stack"))
slf.warn = 0
}
return slf.generator()

View File

@ -0,0 +1,32 @@
package concurrent_test
import (
"github.com/kercylan98/minotaur/utils/concurrent"
"github.com/kercylan98/minotaur/utils/times"
"testing"
"time"
)
func TestPool_EAC(t *testing.T) {
var p = concurrent.NewPool[int](10, func() int {
return 0
}, func(data int) {
})
go func() {
for i := 0; i < 1000; i++ {
go func() {
for {
p.Release(p.Get())
}
}()
}
}()
go func() {
time.Sleep(2 * time.Second)
p.EAC(2048)
}()
time.Sleep(100 * times.Day)
}