You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

379 lines
8.2 KiB

package memory
import (
"runtime"
"sync"
"time"
"github.com/sirupsen/logrus"
)
// BufferPool 缓冲区池
type BufferPool struct {
pools map[int]*sync.Pool
sizes []int
logger *logrus.Logger
stats BufferStats
}
// BufferStats 缓冲区统计
type BufferStats struct {
mu sync.RWMutex
Gets int64 `json:"gets"`
Puts int64 `json:"puts"`
News int64 `json:"news"`
Reuses int64 `json:"reuses"`
TotalAlloc int64 `json:"totalAlloc"`
TotalReused int64 `json:"totalReused"`
}
// MemoryMonitor 内存监控器
type MemoryMonitor struct {
logger *logrus.Logger
ticker *time.Ticker
stopCh chan struct{}
thresholds Thresholds
lastStats runtime.MemStats
callbacks []MemoryCallback
mu sync.RWMutex
}
// Thresholds 内存阈值配置
type Thresholds struct {
HeapAllocMB int64 `json:"heapAllocMB"`
HeapSysMB int64 `json:"heapSysMB"`
GCPercent int `json:"gcPercent"`
ForceGCThreshMB int64 `json:"forceGCThreshMB"`
}
// MemoryCallback 内存回调函数
type MemoryCallback func(stats runtime.MemStats)
// Config 内存管理配置
type Config struct {
BufferSizes []int `json:"bufferSizes"`
MonitorInterval time.Duration `json:"monitorInterval"`
Thresholds Thresholds `json:"thresholds"`
EnableAutoGC bool `json:"enableAutoGC"`
EnableOptimization bool `json:"enableOptimization"`
}
// Manager 内存管理器
type Manager struct {
bufferPool *BufferPool
monitor *MemoryMonitor
config Config
logger *logrus.Logger
}
// NewManager 创建内存管理器
func NewManager(config Config, logger *logrus.Logger) *Manager {
// 设置默认值
if len(config.BufferSizes) == 0 {
config.BufferSizes = []int{512, 1024, 2048, 4096, 8192, 16384, 32768, 65536}
}
if config.MonitorInterval == 0 {
config.MonitorInterval = 30 * time.Second
}
if config.Thresholds.HeapAllocMB == 0 {
config.Thresholds.HeapAllocMB = 100
}
if config.Thresholds.HeapSysMB == 0 {
config.Thresholds.HeapSysMB = 200
}
if config.Thresholds.GCPercent == 0 {
config.Thresholds.GCPercent = 100
}
if config.Thresholds.ForceGCThreshMB == 0 {
config.Thresholds.ForceGCThreshMB = 500
}
manager := &Manager{
config: config,
logger: logger,
}
// 创建缓冲区池
if config.EnableOptimization {
manager.bufferPool = NewBufferPool(config.BufferSizes, logger)
}
// 创建内存监控器
manager.monitor = NewMemoryMonitor(config.MonitorInterval, config.Thresholds, logger)
// 启用自动GC
if config.EnableAutoGC {
manager.monitor.AddCallback(manager.autoGCCallback)
}
return manager
}
// NewBufferPool 创建缓冲区池
func NewBufferPool(sizes []int, logger *logrus.Logger) *BufferPool {
bp := &BufferPool{
pools: make(map[int]*sync.Pool),
sizes: make([]int, len(sizes)),
logger: logger,
}
copy(bp.sizes, sizes)
// 为每个大小创建池
for _, size := range sizes {
sz := size // 捕获循环变量
bp.pools[sz] = &sync.Pool{
New: func() interface{} {
bp.stats.incNews()
bp.stats.addTotalAlloc(int64(sz))
return make([]byte, sz)
},
}
}
return bp
}
// Get 获取缓冲区
func (bp *BufferPool) Get(size int) []byte {
bp.stats.incGets()
// 找到最合适的大小
for _, poolSize := range bp.sizes {
if size <= poolSize {
buf := bp.pools[poolSize].Get().([]byte)
bp.stats.incReuses()
bp.stats.addTotalReused(int64(poolSize))
return buf[:size]
}
}
// 没有合适的池,创建新缓冲区
bp.stats.incNews()
bp.stats.addTotalAlloc(int64(size))
return make([]byte, size)
}
// Put 归还缓冲区
func (bp *BufferPool) Put(buf []byte) {
if buf == nil {
return
}
bp.stats.incPuts()
capacity := cap(buf)
// 找到对应的池
for _, poolSize := range bp.sizes {
if capacity == poolSize {
bp.pools[poolSize].Put(buf[:poolSize])
return
}
}
}
// GetStats 获取缓冲区统计
func (bp *BufferPool) GetStats() BufferStats {
bp.stats.mu.RLock()
defer bp.stats.mu.RUnlock()
return bp.stats
}
// NewMemoryMonitor 创建内存监控器
func NewMemoryMonitor(interval time.Duration, thresholds Thresholds, logger *logrus.Logger) *MemoryMonitor {
monitor := &MemoryMonitor{
logger: logger,
ticker: time.NewTicker(interval),
stopCh: make(chan struct{}),
thresholds: thresholds,
callbacks: make([]MemoryCallback, 0),
}
// 启动监控
go monitor.run()
return monitor
}
// AddCallback 添加内存回调
func (mm *MemoryMonitor) AddCallback(callback MemoryCallback) {
mm.mu.Lock()
mm.callbacks = append(mm.callbacks, callback)
mm.mu.Unlock()
}
// Stop 停止监控
func (mm *MemoryMonitor) Stop() {
close(mm.stopCh)
mm.ticker.Stop()
}
// run 运行监控
func (mm *MemoryMonitor) run() {
for {
select {
case <-mm.stopCh:
return
case <-mm.ticker.C:
mm.check()
}
}
}
// check 检查内存状态
func (mm *MemoryMonitor) check() {
var stats runtime.MemStats
runtime.ReadMemStats(&stats)
// 记录内存统计
heapAllocMB := stats.HeapAlloc / 1024 / 1024
heapSysMB := stats.HeapSys / 1024 / 1024
mm.logger.WithFields(logrus.Fields{
"heap_alloc_mb": heapAllocMB,
"heap_sys_mb": heapSysMB,
"gc_num": stats.NumGC,
"goroutines": runtime.NumGoroutine(),
}).Debug("Memory stats")
// 检查阈值
if int64(heapAllocMB) > mm.thresholds.HeapAllocMB {
mm.logger.WithField("heap_alloc_mb", heapAllocMB).Warn("Heap allocation threshold exceeded")
}
if int64(heapSysMB) > mm.thresholds.HeapSysMB {
mm.logger.WithField("heap_sys_mb", heapSysMB).Warn("Heap system threshold exceeded")
}
// 强制GC阈值
if int64(heapAllocMB) > mm.thresholds.ForceGCThreshMB {
mm.logger.WithField("heap_alloc_mb", heapAllocMB).Info("Force GC triggered")
runtime.GC()
}
// 调用回调函数
mm.mu.RLock()
for _, callback := range mm.callbacks {
go callback(stats)
}
mm.mu.RUnlock()
mm.lastStats = stats
}
// GetStats 获取最新内存统计
func (mm *MemoryMonitor) GetStats() runtime.MemStats {
return mm.lastStats
}
// Manager 方法
// GetBuffer 获取缓冲区
func (m *Manager) GetBuffer(size int) []byte {
if m.bufferPool != nil {
return m.bufferPool.Get(size)
}
return make([]byte, size)
}
// PutBuffer 归还缓冲区
func (m *Manager) PutBuffer(buf []byte) {
if m.bufferPool != nil {
m.bufferPool.Put(buf)
}
}
// GetBufferStats 获取缓冲区统计
func (m *Manager) GetBufferStats() BufferStats {
if m.bufferPool != nil {
return m.bufferPool.GetStats()
}
return BufferStats{}
}
// GetMemoryStats 获取内存统计
func (m *Manager) GetMemoryStats() runtime.MemStats {
return m.monitor.GetStats()
}
// Stop 停止内存管理器
func (m *Manager) Stop() {
if m.monitor != nil {
m.monitor.Stop()
}
}
// ForceGC 强制垃圾回收
func (m *Manager) ForceGC() {
m.logger.Info("Manual GC triggered")
runtime.GC()
}
// autoGCCallback 自动GC回调
func (m *Manager) autoGCCallback(stats runtime.MemStats) {
heapAllocMB := stats.HeapAlloc / 1024 / 1024
// 当堆分配超过阈值时触发GC
if int64(heapAllocMB) > m.config.Thresholds.ForceGCThreshMB {
m.ForceGC()
}
}
// GetOverallStats 获取总体统计信息
func (m *Manager) GetOverallStats() map[string]interface{} {
memStats := m.GetMemoryStats()
bufferStats := m.GetBufferStats()
return map[string]interface{}{
"memory": map[string]interface{}{
"heap_alloc_mb": memStats.HeapAlloc / 1024 / 1024,
"heap_sys_mb": memStats.HeapSys / 1024 / 1024,
"gc_num": memStats.NumGC,
"goroutines": runtime.NumGoroutine(),
},
"buffers": bufferStats,
"config": map[string]interface{}{
"optimization_enabled": m.config.EnableOptimization,
"auto_gc_enabled": m.config.EnableAutoGC,
"buffer_sizes": m.config.BufferSizes,
},
}
}
// BufferStats 方法
func (bs *BufferStats) incGets() {
bs.mu.Lock()
bs.Gets++
bs.mu.Unlock()
}
func (bs *BufferStats) incPuts() {
bs.mu.Lock()
bs.Puts++
bs.mu.Unlock()
}
func (bs *BufferStats) incNews() {
bs.mu.Lock()
bs.News++
bs.mu.Unlock()
}
func (bs *BufferStats) incReuses() {
bs.mu.Lock()
bs.Reuses++
bs.mu.Unlock()
}
func (bs *BufferStats) addTotalAlloc(size int64) {
bs.mu.Lock()
bs.TotalAlloc += size
bs.mu.Unlock()
}
func (bs *BufferStats) addTotalReused(size int64) {
bs.mu.Lock()
bs.TotalReused += size
bs.mu.Unlock()
}