Golang 踩坑pprof分析
价格49元一个,一次注册终身使用
另送科学上网教程,ChatGPT使用教程
联系方式:加微信搜 xingyi4200
案例1:Golang内存泄露
## 影响情况##
服务A内存泄露,造成服务器内存不足,系统运行的服务A 因为OOM 被强制KILL 掉、导致任务丢失
##分析思路##
Golang 编写的服务遇到OOM情况如何分析处理那?首先我们利用golang 自带的pprof来分析。在main.go中 增加`
go func() {
if err := http.ListenAndServe("0.0.0.0:12345", nil); err != nil {
log.Println(err)
}
}()`
然后再结合火焰图 去分析<以下是两张火焰图>
图1
图2
从图1 和图2 得知-sql map 有内存泄露 sql 也有内存泄露、 目前260w 的数据,每天跑N次。 每次会切割成M次子任务、 所以会泄露N*M次
由于通过火焰图我们追踪到了泄露的Func ,那么我们直接定位到相应源码去查看下·
从图中可以看出、这个清空操作失效、因为time.Now().Day() 永远和w.FrequencyControlFormat.Day 一致。另外每次new 都是新的引用、新的地址、导致每次都会将数据库数据全量load到map内存中,不会被释放、
另外我们再通过debug/pprof 去查看下各项详细情况
可以看出goroutine 数量一直在增加,没有被释放掉。因为channel 没有主动关闭、导致还会夯住对应的goroutine,所以要注意channel 的使用要及时关闭,否则也会造成资源的浪费、
那么我们在分析一下并发安全的map 里面存储的数据为什么是引用的数据库的数据源地址
func (m *Map) Store(key, value interface{}) {
// 如果read存在这个键,并且这个entry没有被标记删除,尝试直接写入,写入成功,则结束
// 第一次检测
read, _ := m.read.Load().(readOnly)
if e, ok := read.m[key]; ok && e.tryStore(&value) {
return
}
// dirty map锁
m.mu.Lock()
// 第二次检测
read, _ = m.read.Load().(readOnly)
if e, ok := read.m[key]; ok {
// unexpungelocc确保元素没有被标记为删除
// 判断元素被标识为删除
if e.unexpungeLocked() {
// 这个元素之前被删除了,这意味着有一个非nil的dirty,这个元素不在里面.
m.dirty[key] = e
}
// 更新read map 元素值
e.storeLocked(&value)
} else if e, ok := m.dirty[key]; ok {
// 此时read map没有该元素,但是dirty map有该元素,并需修改dirty map元素值为最新值
e.storeLocked(&value)
} else {
// read.amended==false,说明dirty map为空,需要将read map 复制一份到dirty map
if !read.amended {
m.dirtyLocked()
// 设置read.amended==true,说明dirty map有数据
m.read.Store(readOnly{m: read.m, amended: true})
}
// 设置元素进入dirty map,此时dirty map拥有read map和最新设置的元素
m.dirty[key] = newEntry(value)
}
// 解锁,有人认为锁的范围有点大,假设read map数据很大,那么执行m.dirtyLocked()会耗费花时间较多,完全可以在操作dirty map时才加锁,这样的想法是不对的,因为m.dirtyLocked()中有写入操作
m.mu.Unlock()
}
//重点在这里 引用-
//导致forrange 数据库的数据的时候 -数据库的数据不能被释放~
func newEntry(i interface{}) *entry {
return &entry{p: unsafe.Pointer(&i)}
}
到此这篇关于“Golang 踩坑pprof分析”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!
您可能感兴趣的文章:
使用pprof进行golang程序内存分析
golang http client 使用gzip_一次gRPC使用不当导致goroutine泄漏排查记录
Golang pprof 性能分析与火焰图
Golang-性能监控及调优
golang pprof 的原理分析
golang 踩坑
踩了 Golang sync.Map 的一个坑
golang 反射_golang 内存管理分析
golang map并发读写问题踩坑记录 `concurrent map read and map write`
golang 利用github自定义module 踩坑系列 类似于「springboot starter 一毛一样」