情境导入
产线一个问题:业务系统调用后台超时,问是不是 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 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
$ 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