package utils import ( "log" "runtime" "time" ) // MemoryMonitor 内存监控器 type MemoryMonitor struct { maxHeapMB uint64 // 最大堆内存阈值(MB) maxGoroutines int // 最大goroutine数量阈值 checkInterval time.Duration // 检查间隔 running bool // 是否运行中 stopChan chan bool } // NewMemoryMonitor 创建新的内存监控器 func NewMemoryMonitor(maxHeapMB uint64, maxGoroutines int, checkInterval time.Duration) *MemoryMonitor { return &MemoryMonitor{ maxHeapMB: maxHeapMB, maxGoroutines: maxGoroutines, checkInterval: checkInterval, stopChan: make(chan bool, 1), } } // Start 启动内存监控 func (mm *MemoryMonitor) Start() { if mm.running { return } mm.running = true go mm.monitor() } // Stop 停止内存监控 func (mm *MemoryMonitor) Stop() { if !mm.running { return } mm.running = false select { case mm.stopChan <- true: default: } } // monitor 监控循环 func (mm *MemoryMonitor) monitor() { ticker := time.NewTicker(mm.checkInterval) defer ticker.Stop() for { select { case <-ticker.C: mm.checkMemory() case <-mm.stopChan: return } } } // checkMemory 检查内存使用情况 func (mm *MemoryMonitor) checkMemory() { var m runtime.MemStats runtime.ReadMemStats(&m) heapMB := m.HeapInuse / 1024 / 1024 goroutineCount := runtime.NumGoroutine() // 检查堆内存使用 if heapMB > mm.maxHeapMB { log.Printf("[WARN] 内存使用警告: 堆内存使用过高 %d MB (阈值: %d MB)", heapMB, mm.maxHeapMB) // 尝试触发GC runtime.GC() // 再次检查 runtime.ReadMemStats(&m) heapMBAfterGC := m.HeapInuse / 1024 / 1024 log.Printf("[INFO] GC后堆内存: %d MB", heapMBAfterGC) } // 检查goroutine数量 if goroutineCount > mm.maxGoroutines { log.Printf("[WARN] Goroutine数量警告: 当前数量 %d (阈值: %d)", goroutineCount, mm.maxGoroutines) } } // GetMemoryStats 获取当前内存统计信息 func (mm *MemoryMonitor) GetMemoryStats() map[string]interface{} { var m runtime.MemStats runtime.ReadMemStats(&m) return map[string]interface{}{ "heap_inuse_mb": m.HeapInuse / 1024 / 1024, "heap_alloc_mb": m.HeapAlloc / 1024 / 1024, "sys_mb": m.Sys / 1024 / 1024, "num_gc": m.NumGC, "num_goroutines": runtime.NumGoroutine(), "last_gc_time": time.Unix(0, int64(m.LastGC)), } } // ForceGC 强制执行垃圾回收 func (mm *MemoryMonitor) ForceGC() { before := mm.getHeapSize() runtime.GC() after := mm.getHeapSize() // 使用log包直接输出,避免undefined common错误 log.Printf("[INFO] 强制GC: 释放内存 %d MB", (before-after)/1024/1024) } // getHeapSize 获取当前堆大小 func (mm *MemoryMonitor) getHeapSize() uint64 { var m runtime.MemStats runtime.ReadMemStats(&m) return m.HeapInuse } // 默认内存监控器实例 var DefaultMemMonitor = NewMemoryMonitor( 512, // 最大堆内存512MB 1000, // 最大1000个goroutines 30*time.Second, // 30秒检查一次 ) // StartDefaultMonitor 启动默认内存监控器 func StartDefaultMonitor() { DefaultMemMonitor.Start() } // StopDefaultMonitor 停止默认内存监控器 func StopDefaultMonitor() { DefaultMemMonitor.Stop() }