记一次使用gdb诊断gc问题全过程
Posted 扣钉日记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次使用gdb诊断gc问题全过程相关的知识,希望对你有一定的参考价值。
原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。
简介
上次解决了GC长耗时问题后,系统果然平稳了许多,这是之前的文章《GC耗时高,原因竟是服务流量小?》
然而,过了一段时间,我检查GC日志时,又发现了一个GC问题,如下:
从这个图中可以发现,我们GC有一些尖峰,有时会突然有大量的内存分配。
查看GC日志,发现有大对象分配的记录,如下:
$ grep \'concurrent humongous allocation\' gc.log | awk \'match($0,/allocation request: (\\w+) bytes/,a)print a[1]\' |sort -nr
1941835784
1889656848
可以看到,一次大对象分配,分配大小竟然有1.9G,这谁能抗得住啊!
async-profiler定位大对象分配
上面提到的文章介绍过,使用async-profiler可以很容易的定位大对象分配的调用栈,方法如下:
./profiler.sh start --all-user -e G1CollectedHeap::humongous_obj_allocate -f ./humongous.jfr jps
然后使用jmc打开humongous.jfr文件,调用栈如下:
这是在做thrift反序列化操作,调用了TCompactProtocol.readDouble
方法,方法代码如下:
可是,这里只创建了8字节的数组,怎么也不可能需要分配1.9G内存吧,真是奇了怪了!
经过一番了解,这是因为async-profiler是通过AsyncGetCallTrace来获取调用栈的,而AsyncGetCallTrace获取的栈有时是不准的,Java社区有反馈过这个问题,至今未解决。
问题链接:https://bugs.openjdk.org/browse/JDK-8178287
寻找其它tracer
linux上有很多内核态的tracer,如perf、bcc、systemtap,但它们都需要root权限,而我是不可能申请到这个权限的
以上是关于记一次使用gdb诊断gc问题全过程的主要内容,如果未能解决你的问题,请参考以下文章
记一次 CMS GC导致 FULL GC 时间开销很大的排查
记一次 CMS GC导致 FULL GC 时间开销很大的排查