情境导入

产线一个问题:业务系统调用后台超时,问是不是 FULL GC 的问题。

查看方式

  • 知道 GC 文件的位置

··· locate xxx.log ···

  • 知道如何查看 FULL GC 日志
cat /XXX/gc.log | grep -a 'Full'| more

简单分析

直接根据 full gc 的关键词查看。

一般在并发较高的系统中会出现这种日志,且几天出现一次。

但是一旦出现,一次 FULL GC 可能时间多达 10S,就会导致外部调用超时。

教训

你应该知道如何让系统打印 GC 日志,并且当系统调用超时的时候,可以联系到 FULL GC,并会排查。

  • 问题2

线上每台机器去看的效率实在不高,建议有一个监控系统。

可以在第一时间获取到 FULL GC 的日志,并且发送邮件/短信通知给相关负责人。

IDEA 中打印 GC 日志

编写测试类

public class Main {

    public static void main(String[] args) throws InterruptedException {
        List<String> stringList = new ArrayList<>();
        while (true) {
            for(int i = 0; i < 10000; i++) {
                stringList.add(UUID.randomUUID().toString());
            }
            TimeUnit.SECONDS.sleep(1);
            System.out.println(stringList.size());
        }
    }
}

配置运行 jvm 参数

【run】=>【Edit Configration】=>【vm option】

  • 打印 GC 日志信息
-XX:+PrintGCDetails

测试日志如下:

10000
20000
30000
[GC (Allocation Failure) [PSYoungGen: 33280K->4689K(38400K)] 33280K->4697K(125952K), 0.0032247 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
40000
50000
60000
70000
[GC (Allocation Failure) [PSYoungGen: 37969K->5112K(38400K)] 37977K->9224K(125952K), 0.0046176 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
80000

简单分析

[GC (Allocation Failure) [PSYoungGen: 33280K->4689K(38400K)] 33280K->4697K(125952K), 0.0032247 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

GC 日志

GC 原因:Allocation Failure

GC 类型:PSYoungGen

GC 效果: 33280K->4689K(38400K)

GC 消耗时间:Times: user=0.00 sys=0.00, real=0.00 secs

没有打印 gc.log

场景

有时候一台机器会出现,没有设置 jvm 打印日志怎么办呢。

命令 jstat

jstat -gcutil <pid>

如何查看 pid

$ jps
29296 Jps
28710 jboss-modules.jar

首先获取 pid

$ps -ef | grep "projectName"
projectName   15599 15514 52 Jul02 ?        08:45:15 /bea/jdk1.7.0_99/bin/java -D[Standalone] 

可知对应 pid=15599

执行命令

jstat -gcutil 15599

日志信息如下:

S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
0.00  98.97   2.71  79.48  53.54   3759  118.032     2    0.951  118.984
  • 字段解释

S0 :年轻代中第一个survivor(幸存区)已使用的占当前容量百分比 S1 :年轻代中第二个survivor(幸存区)已使用的占当前容量百分比 E :年轻代中Eden(伊甸园)已使用的占当前容量百分比 O :old代已使用的占当前容量百分比 P :perm代已使用的占当前容量百分比 YGC :从应用程序启动到采样时年轻代中gc次数 YGCT :从应用程序启动到采样时年轻代中gc所用时间(s) FGC :从应用程序启动到采样时old代(全gc)gc次数 FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s) GCT:从应用程序启动到采样时gc用的总时间(s)

统计监控

jstat -gcutil pid 300 >/tmp/gc.log

300 是一个时间间隔,单位为 ms,但是不要低于 50,会失去意义。

这个对性能损耗比较小,生产可以使用,但是不要使用 jmap/jstatck

如何查看的 GC 器类型

命令

java -XX:+PrintCommandLineFlags -version

效果

-XX:InitialHeapSize=128975232 -XX:MaxHeapSize=2063603712 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

各个版本默认类型

jdk1.7 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)

jdk1.8 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)

jdk1.9 默认垃圾收集器G1

jboss 默认配置文件地址

/app/xxx/jboss/bin/standalone.conf

拓展阅读

jmap

jstat

jconsole

参考资料

在IDE的后台打印GC日志

JVM的GC日志的主要参数

【GC分析】Java GC日志查看

jvm 性能调优工具之 jstat

JVM系列:查看JVM使用的什么垃圾收集器