首次提交:初始化项目代码

This commit is contained in:
sunct
2026-07-31 15:18:32 +08:00
commit d6393266b0
193 changed files with 14287 additions and 0 deletions
+100
View File
@@ -0,0 +1,100 @@
package main
import (
"fmt"
"log"
"net/http"
_ "net/http/pprof"
"runtime"
"sync"
"time"
)
// leakSlice 全局切片,持续追加数据导致内存泄漏
var leakSlice [][]byte
// generateLeak 模拟内存泄漏
func generateLeak() {
for {
// 每次分配10MB,追加到全局切片(永久引用,无法回收)
leakSlice = append(leakSlice, make([]byte, 10*1024*1024))
time.Sleep(100 * time.Millisecond)
// 打印当前内存状态
var stats runtime.MemStats
runtime.ReadMemStats(&stats)
fmt.Printf("当前堆内存:%d MBGC次数:%d\n", stats.HeapAlloc/1024/1024, stats.NumGC)
}
}
func generateLeak1() {
var maxMem uint64 = 500 // 最大允许占用500MB内存
for {
leakSlice = append(leakSlice, make([]byte, 10*1024*1024))
time.Sleep(100 * time.Millisecond)
var stats runtime.MemStats
runtime.ReadMemStats(&stats)
curMem := stats.HeapAlloc / 1024 / 1024
fmt.Printf("当前堆内存:%d MBGC次数:%d\n", curMem, stats.NumGC)
// ✅ 核心修复:内存超限后,置空全局切片,切断引用
if curMem >= maxMem {
leakSlice = nil // 关键一行!置空后,原切片的所有[]byte都失去引用
runtime.GC() // 手动触发GC,立刻回收内存
fmt.Println("=== 内存超限,已释放所有内存 ===")
}
}
}
func generateLeak2() {
maxLen := 20 // 最多保留20个10MB切片,总内存上限200MB
for {
leakSlice = append(leakSlice, make([]byte, 10*1024*1024))
// ✅ 核心修复:超过最大长度,删除头部旧数据,释放引用
if len(leakSlice) > maxLen {
leakSlice = leakSlice[1:] // 切片切片,丢弃第一个元素,GC会回收它
}
time.Sleep(100 * time.Millisecond)
var stats runtime.MemStats
runtime.ReadMemStats(&stats)
fmt.Printf("当前堆内存:%d MBGC次数:%d,切片长度:%d\n", stats.HeapAlloc/1024/1024, stats.NumGC, len(leakSlice))
}
}
// ✅ 定义10MB切片的对象池
var needBytePool = sync.Pool{
New: func() interface{} {
return make([]byte, 10*1024*1024) // 每次创建10MB切片
},
}
// 无内存泄漏!复用内存,不持有永久引用
func generateLeak3() {
for {
// 从池子里拿切片,复用内存
buf := needBytePool.Get().([]byte)
// 模拟业务使用
_ = buf
// 使用完放回池子,供后续复用,释放引用
needBytePool.Put(buf[:0])
time.Sleep(100 * time.Millisecond)
var stats runtime.MemStats
runtime.ReadMemStats(&stats)
fmt.Printf("当前堆内存:%d MBGC次数:%d\n", stats.HeapAlloc/1024/1024, stats.NumGC)
}
}
func main() {
// 启动pprof服务
go func() {
log.Println("pprof服务启动:http://localhost:6060/debug/pprof/")
log.Fatal(http.ListenAndServe(":6060", nil))
}()
// 模拟内存泄漏
go generateLeak3()
// 运行60秒,便于诊断
time.Sleep(60 * time.Second)
}