记一次使用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问题全过程的主要内容,如果未能解决你的问题,请参考以下文章

记一次线上FGC问题排查

记一次OOM查询处理过程

记一次 CMS GC导致 FULL GC 时间开销很大的排查

记一次 CMS GC导致 FULL GC 时间开销很大的排查

记一次 CMS GC导致 FULL GC 时间开销很大的排查

记一次 CMS GC导致 FULL GC 时间开销很大的排查