wolfogre / blog-utterances

utterances of my blog.
5 stars 0 forks source link

golang pprof 实战 #39

Open wolfogre opened 5 years ago

wolfogre commented 5 years ago

https://blog.wolfogre.com/posts/go-ppof-practice/

bluntdel commented 5 years ago

感谢,对pprof有了最基本的了解和使用,但还是浅显了点,期待下篇。

duncanwang commented 5 years ago

超级棒,我注明出处,转载一下哦。

yanjinbin commented 4 years ago

为什么我的web svg没有dog 函数分支啊

wolfogre commented 4 years ago

@yanjinbin 可以说明下是哪一步不符合预期吗?如果是“排查频繁内存回收”那一步,请确认下有没有让程序先运行几分钟再执行 go pporf,时间间隔过短的话可能从 profile 里看不出东西。

yanjinbin commented 4 years ago

@yanjinbin 可以说明下是哪一步不符合预期吗?如果是“排查频繁内存回收”那一步,请确认下有没有让程序先运行几分钟再执行 go pporf,时间间隔过短的话可能从 profile 里看不出东西。

image cpu内存过高 就这个红色标注的分支 我web生成不了
我的如下 image 我确实运行了4min左右,时间应该够了吧 环境信息: go version go1.13.4 darwin/amd64

yanjinbin commented 4 years ago

还有 火焰图🔥 跟这个pprof差不多吧 为什么uber的 go torch要说 1.11以上都整合到pprof上面去了呢 纳闷

wolfogre commented 4 years ago

@yanjinbin 这是正常现象,因为我写的代码只是靠疯狂循环来提升CPU占用率,并不能精准控制占用多少,况且 pprof 采样也会有一些误差,你可以看到我的 tiger 占用是 89.18%,而你的是 96.85%,而这个树形调用栈图只会显示占用较高的调用栈,不是所有的调用栈,那样的话图就没法看了,所以你的图里,dog 的 CPU 占用实际上是被认为太小了所以被忽略了。这不重要,重要的 tiger 被正确发现了。

所以火焰图的优点就在这里,它是另一种图形化展示调用栈资源占用的方式,不仅能突出资源占用的大户,对于占用量不高的调用栈也不会完全丢失细节,但可能没有树形调用栈图这么直白易懂。

yanjinbin commented 4 years ago

@yanjinbin 这是正常现象,因为我写的代码只是靠疯狂循环来提升CPU占用率,并不能精准控制占用多少,况且 pprof 采样也会有一些误差,你可以看到我的 tiger 占用是 89.18%,而你的是 96.85%,而这个树形调用栈图只会显示占用较高的调用栈,不是所有的调用栈,那样的话图就没法看了,所以你的图里,dog 的 CPU 占用实际上是被认为太小了所以被忽略了。这不重要,重要的 tiger 被正确发现了。

所以火焰图的优点就在这里,它是另一种图形化展示调用栈资源占用的方式,不仅能突出资源占用的大户,对于占用量不高的调用栈也不会完全丢失细节,但可能没有树形调用栈图这么直白易懂。 嗯 谢谢,我现在想知道的就是 火焰图 到底有没有可以用1.13版本的pprof展现呢 之前是uber go torch项目

yanjinbin commented 4 years ago

楼主 现在的火焰图 还是用uber的go torch吗 不是说整合到pprof上面去了?

yanjinbin commented 4 years ago

1数据采样: go tool pprof pprof http://127.0.0.1:[端口号]/debug/pprof/profile -seconds [采样间隔时间数字]

go tool pprof pprof http://127.0.0.1:6060/debug/pprof/profile -seconds 10

2生成火焰图 : go tool pprof -http=:8081 ~/pprof/[文件路径名].pb.gz

wolfogre commented 4 years ago

@yanjinbin go-torch 已经废弃了,pprof 整合了火焰图这事儿我之前确实不知道。

刚试了一下你写的步骤,赞👍。不过有个笔误哈,你想说的应该是:

go tool pprof -seconds [采样间隔时间数字] http://127.0.0.1:[端口号]/debug/pprof/profile
wolfogre commented 4 years ago

来自 @wenchaopeng 于 issue #1 的提问:


pprof统计的内存与PC上显示的内存不符合

你好,看了你写的关于pprof的博客,写的很好,不过有一个问题,你那个炸弹程序占用内存大概2GB,我在linux下跑了,通过htop查看,确实在2GB左右,但是通过pprof查看,只能查到1GB内存占用,请教一下这是为什么,两边内存对不上,请解惑!


好问题哈。是这样的,代码中一共有两处有意消耗内存,一处是这里:

func (m *Mouse) Steal() {
    log.Println(m.Name(), "steal")
    max := constant.Gi
    for len(m.buffer) * constant.Mi < max {
        m.buffer = append(m.buffer, [constant.Mi]byte{})
    }
}

可以看到这里的逻辑是占上不超过 1G 内存,所以 pprof 查到 1G 内存是符合预期的。

另一处是这里:

func (d *Dog) Run() {
    log.Println(d.Name(), "run")
    _ = make([]byte, 16 * constant.Mi)
}

这里故意申请 16M 内存并立即丢弃,这里本意是为了模拟一个频繁 GC 问题,因为上文已经占了 1G 内存不放,所以 golang 每次 GC 结束,会发现还占用了 1G,所以 GC 策略会在下次内存占用超过 1G * 2 时(具体为什么是两倍可以看下 GC 策略相关资料)再次触发 GC 降回 1G,所以站在操作系统来看,这个程序的内存占用是在 1GB - 2GB 之间的(注意 GC 掉的内存并不一定会立即返还给操作系统),而我说 “程序会占用约 2G 内存” 是说了最坏情况,意思是你至少得有 2G 内存。

然后你应该意识到一个问题了,pprof 看到的内存占用,其实只是 golang 逻辑上正在使用的内存量,不包括已被 GC 回收但尚未返还给操作系统的内存,同样也不包括内核态的内存占用。而 htop 是站在操作系统层面看到的进程内存占用,理论上就是会比 pprof 看到的内存占用量更多的。

如果你在实际工作中发现 htop 看到内存占用贼大,pprof 看到内存占用却不多,就要考虑下,是不是有大量内存被 GC 但还没来得及返还给操作系统,是不是某些内核态操作(比如 IO)消耗了大量内存。


lieinsun commented 4 years ago

哇哦,超级棒的文章,教程向的博客一顿好找啊

wdd817 commented 4 years ago

讲道理, 粗浅但是特别棒的入门文章, 👍

Tracy-Hu commented 4 years ago

优质文章o( ̄▽ ̄)d关于排查阻塞部分,我按照步骤一步步到这里后,block数量显示为1而不是文中的2啦,所以小编最后的疑点是不是没问题的~另外,web生成的图,里面的虚线代表什么意思呀?麻烦小编帮忙解答下Thanks♪(・ω・)ノ

SeasonWoo commented 3 years ago

写的很棒,对于入门真的特别有帮助!

kevinx1 commented 3 years ago

很全面,学习中!

chaggle commented 2 years ago

好耶!

jieyuefeng commented 2 years ago

你好,文中《Golang 大杀器之性能剖析 PProf》链接更新到了https://github.com/eddycjy/blog/blob/master/content/posts/go/tools/2018-09-15-go-tool-pprof.md

lyfwfm commented 2 years ago

请问该方法能在生产环境使用吗?我担心pprof连上生产环境进程(因为进程此时已经cpu和内存很高了),导致进程直接挂掉。

wolfogre commented 2 years ago

请问该方法能在生产环境使用吗?我担心pprof连上生产环境进程(因为进程此时已经cpu和内存很高了),导致进程直接挂掉。

@lyfwfm 可以参考这篇文章:Continuous Profiling of Go programs

MoneyHappy commented 1 year ago

请教下,有这么个情景:可能应用程序是在一台打包机打好,然后二进制文件传到另一台机器运行,这时 list 就无法查看代码信息了,因为找不到代码位置了。 请问下这个一般有什么解决办法么

wolfogre commented 1 year ago

请教下,有这么个情景:可能应用程序是在一台打包机打好,然后二进制文件传到另一台机器运行,这时 list 就无法查看代码信息了,因为找不到代码位置了。 请问下这个一般有什么解决办法么

编译的时候加了 -ldflags "-s -w",去掉了调试信息?

yy57 commented 1 year ago

牛!这个是真的牛!看完就知道怎么实操了

mxisc commented 1 year ago

很棒的一篇文章,为防止后续因为某些因素该贴无法访问,我进行了转载,并且已经表明了转载出处,供后续自己学习使用

wxsms commented 1 year ago

非常棒的文章!感谢分享!

haohui03 commented 10 months ago

写的很好,学习了!!!!

StealingChair commented 1 month ago

感谢分享!由浅入深,很棒的文章。