线上出现fullgc问题如何排查?

2,928 阅读2分钟

1.问题描述

线上出现fullgc报警,每5分钟一次

2.背景知识

  1. 程序执行了System.gc()
  1. 执行了jmap -histo:live pid命令

  2. 在执行minor gc的时候进行的一系列检查

    执行Minor GC的时候,JVM会检查老年代中最大连续可用空间是否大于了当前新生代所有对象的总大小。 如果大于,则直接执行Minor GC(这个时候执行是没有风险的)。 如果小于了,JVM会检查是否开启了空间分配担保机制,如果没有开启则直接改为执行Full GC。 如果开启了,则JVM会检查老年代中最大连续可用空间是否大于了历次晋升到老年代中的平均大小,如果小于则执行改为执行Full GC。 如果大于则会执行Minor GC,如果Minor GC执行失败则会执行Full GC

  1. 使用了大对象
  1. 在程序中长期持有了对象的引用

3.排查步骤

注意: JVM在执行dump操作的时候是会发生stop the word事件的,也就是说此时所有的用户线程都会暂停运行。

3.1通过JVM参数获取dump文件
# 1.线上环境如果有流量需要在启动服务脚本中加入如下JVM参数,表示在发生fullgc的时候自动dump
-XX:HeapDumpBeforeFullGC
# 2.与第一个JVM参数配套使用,指定dump文件的保存路径,便于排查问题,路径也可以是相对路径
-XX:HeapDumpPath=保存dump文件的文件绝对路径

# 说明:如果加入这两个jvm参数还是没有dump下来文件,可能是你的jvm的参数中有其他的参数导致dump失败,排查看是否有如下参数,如果有去掉即可
-XX:+DisableExplicitGC
3.2通过JDK自带的工具jmap获取dump文件
# 导出内存dump文件
jmap -F -dump:live,file=jmap.hprof [PID] 

##### 3.3把dump文件从线上主机下载到本地
命令格式:  
scp local_file remote_username@remote_ip:remote_folder  
或者
scp local_file remote_username@remote_ip:remote_file  
或者
scp local_file remote_ip:remote_folder  
或者
scp local_file remote_ip:remote_file

##### 3.4通过JDK自带的jvisualvm工具分析或者下载三方软件jprofiler来分析dump文件即可

##### 3.5最重要的一点,要把fullgc发生时刻的dump文件和正常没有发生fullgc时间的dump文件都下载到本地,然后对比观察分析方便找到问题的原因