chore: try to control memroy
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
Reference in New Issue
Block a user