问题描述:
某天晚上临时上线了一个定时任务,主要逻辑是定时同步redis上数据到kafka,当天晚上任务执行的时候,由于数据量比较大,16g的内存飙升到百分之八十多,任务执行完成后内存并没有释放,导致监控开始报警,收到报警后重启服务,内存占比占用正常了,其中实现语言是golang。
问题定位:
刚看到这个问题的时候,怀疑是内存泄漏了,秉承这个有怀疑就要动手验证, 怀疑可能由于某种原因程序未释放或无法释放内存, 我们使用gctrace进行内存内存追踪, 查看是否泄漏,同时借助大杀器PProf(pprof 是用于可视化和分析性能分析数据的工具),观察应用程序的情况。
下面代码模拟slice切片demo使用
package main
import (
"fmt"
"net/http"
_ "net/http/pprof" // 添加pprof
"encoding/json"
"time"
)
func main() {
go add()
// 启动
if err := http.ListenAndServe(":6060", nil); err != nil {
panic(err)
}
}
type msg struct {
A int
}
func add() {
i := 5
for i > 0 {
i--
msgs := make([]*msg, 1000000)
j := 1000000
time.Sleep(time.Duration(100)*time.Millisecond)
for j > 0 {
msgs[j-1] = &msg{
A: j,
}
j--
}
go dispose(msgs)
}
}
func dispose(params []*msg) {
msgs := []string{}
for _, v := range params {
value, _ := json.Marshal(v)
msgs = append(msgs, string(value))