chore: try to control memroy

This commit is contained in:
engigu
2026-03-11 14:14:20 +08:00
parent b7522bc47c
commit f9fc33f243
4 changed files with 74 additions and 5 deletions
+4
View File
@@ -11,6 +11,7 @@ import (
"github.com/engigu/baihu-panel/internal/logger"
"github.com/engigu/baihu-panel/internal/router"
"github.com/engigu/baihu-panel/internal/services"
"github.com/engigu/baihu-panel/internal/utils"
"github.com/gin-gonic/gin"
)
@@ -23,12 +24,15 @@ type App struct {
func New() *App {
app := InitBasic()
app.initRouter()
// 初始化完成后回收一次内存
utils.FreeMemory()
return app
}
// InitBasic 初始化基础环境(配置和数据库),不启动后台服务和路由
func InitBasic() *App {
app := &App{}
utils.InitRuntime()
app.initConfig()
app.initDatabase()
return app
+6 -4
View File
@@ -3,7 +3,6 @@ package tasks
import (
"bufio"
"bytes"
"compress/zlib"
"encoding/base64"
"io"
"os"
@@ -225,15 +224,18 @@ func (l *TinyLog) CompressAndCleanup() (string, error) {
// 创建压缩输出缓冲区
var buf bytes.Buffer
b64Writer := base64.NewEncoder(base64.StdEncoding, &buf)
zlibWriter := zlib.NewWriter(b64Writer)
// 使用 Pool 优化压缩
zw := utils.GetZlibWriter(b64Writer)
defer utils.PutZlibWriter(zw)
// 流处理: 文件 -> Zlib -> Base64 -> 缓冲区
if _, err := io.Copy(zlibWriter, f); err != nil {
if _, err := io.Copy(zw, f); err != nil {
return "", err
}
// 关闭写入器以刷新数据
if err := zlibWriter.Close(); err != nil {
if err := zw.Close(); err != nil {
return "", err
}
if err := b64Writer.Close(); err != nil {
+23 -1
View File
@@ -5,21 +5,43 @@ import (
"compress/zlib"
"encoding/base64"
"io"
"sync"
)
var zlibWriterPool = sync.Pool{
New: func() interface{} {
return zlib.NewWriter(io.Discard)
},
}
// GetZlibWriter 从对象池中获取 zlib 写入器
func GetZlibWriter(w io.Writer) *zlib.Writer {
zw := zlibWriterPool.Get().(*zlib.Writer)
zw.Reset(w)
return zw
}
// PutZlibWriter 将 zlib 写入器还回对象池
func PutZlibWriter(zw *zlib.Writer) {
zlibWriterPool.Put(zw)
}
// CompressToBase64 compresses data using zlib and encodes to base64
func CompressToBase64(data string) (string, error) {
if data == "" {
return "", nil
}
var buf bytes.Buffer
zw := zlib.NewWriter(&buf)
zw := GetZlibWriter(&buf)
defer PutZlibWriter(zw)
if _, err := zw.Write([]byte(data)); err != nil {
return "", err
}
if err := zw.Close(); err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(buf.Bytes()), nil
}
+41
View File
@@ -0,0 +1,41 @@
package utils
import (
"os"
"runtime"
"runtime/debug"
"strconv"
"github.com/engigu/baihu-panel/internal/logger"
)
// InitRuntime 设置运行时内存和性能优化参数
func InitRuntime() {
// 从环境变量或配置读取 GOGC
if gogc := os.Getenv("GOGC"); gogc == "" {
// 默认设为 80,比 100 更激进一点,减少 RSS 峰值
debug.SetGCPercent(80)
}
// 从环境变量读取 GOMEMLIMIT (Go 1.19+)
// 建议用户在系统层面设置,例如 BH_MEM_LIMIT=256MiB
if memLimit := os.Getenv("BH_MEM_LIMIT"); memLimit != "" {
// 这里可以解析一下单位,但简单处理可以直接读取字节
if limit, err := strconv.ParseInt(memLimit, 10, 64); err == nil {
debug.SetMemoryLimit(limit)
logger.Infof("[Runtime] 已设置内存上限: %d 字节", limit)
}
}
// 打印当前运行时信息
logger.Infof("[Runtime] CPU 核心数: %d, Goroutine 数量: %d", runtime.NumCPU(), runtime.NumGoroutine())
}
// FreeMemory 显式触发内存回收,释放物理资源给 OS
// 仅建议在执行了超大批量任务或处理了大型文件后调用
func FreeMemory() {
// 触发 GC
runtime.GC()
// 尽可能将内存归还 OS
debug.FreeOSMemory()
}