美文网首页BUG人生
记一次GC导致的CPU与内存冲高的问题解决(附此类问题问题排查流

记一次GC导致的CPU与内存冲高的问题解决(附此类问题问题排查流

作者: 茂茂的小破号 | 来源:发表于2022-06-12 13:08 被阅读0次

    本人在在某次投产期间收到某个模块的一个pod的多次CPU与内存冲高告警,登录到目标Pod控制台使用top命令看到是Java进程CPU消耗。

    接着使用工具查看Java线程信息,本人这里使用的是一个展示Java busy线程的脚本:showbusyjavathreads.sh,传送门:oldratlee/useful-scripts)

    运行脚本可以显示Java进程中的busy的线程并且按照使用率从上至下排列(附上那一次的截图):

    sh showbusyjavathreads.sh
    
    showbusyjavathreads.png

    可以看到有四个GC线程在疯狂GC,前三个甚至达到了99.9%,是GC导致的CPU冲高。

    使用jstack命令查看线程信息,并没有定位到问题,只是看到相关的四个GC线程在处于RUNNERABLE状态。

    jstack pid > stack.txt
    
    jstack.png

    到了这里还是没有排查出具体的问题,下一步打算使用jmap命令进行内存分析。

    jps # 查看java进程
    jmap -dump:format=b,file=jmap.bin pid
    

    把dump好的内存从生产上下载下来后,使用IBM的heapanalyzer进行分析(点击进入下载ha457.jar)。

    # 启动带UI界面的Java内存分析器(这里dump的内存文件较大,故调大了JVM最大内存)
    java -Xmx5G -jar ha457.jar
    

    启动好后会弹出分析界面,选择dump的jmap.bin进行分析。

    内存分析显示有两个WorkLogDomain类型的EntityPage各占了42.5%的堆内存,并且被分析工具标记出了Leak Suspect(蓝色高亮)。

    image.png

    一般EntityPage都是单表交易生成的代码,对应某张表,图中可以看到单个EntityPage的子元素数量为106万个(1067086),感觉像是查了这张表的全量数据。

    image.png

    于是又生产环境工具查询了这张表的记录数量为1069678个,与上面的数量相匹配(这个数据是第二天查的,在此期间内用户又新增了2k条数据)。


    image.png

    由此可以怀疑在CPU内存告警告警的那段时间,这张表在被频繁的查询全量数据,因此JVM也在疯狂的GC。

    进入工程代码,全局搜索WorkLogDomain,发现有一个getAllWorkLogInfo的接口,该方法查询全量WorkLogDomain。至此已找到问题源头。

    相关文章

      网友评论

        本文标题:记一次GC导致的CPU与内存冲高的问题解决(附此类问题问题排查流

        本文链接:https://www.haomeiwen.com/subject/evsgmrtx.html