环境&准备代码
JDK环境
openjdk version "1.8.0_191"
编写一段代码,循环声明对象,并分配 10MB 堆空间,暴露web接口多次调用。
for (int i = 0; i < 100; i++) {
byte[] b1 = new byte[1024 * 1024 * 10];
byte[] b2 = new byte[1024 * 1024 * 10];
byte[] b3 = new byte[1024 * 1024 * 10];
LOG.info("初始化对象...");
}
jstat统计GC执行次数
jstat -gc PID
#或者定时统计,jstat - [-t] [-h] [ []]
#例如:jstat -gc -h3 PID Time Total;
#-h指显示行数,time是每隔多少毫秒输出,total是循环输出多少次(不写就一直输出)
jstat -gc -h3 23081 1000 20
(C=capacity;U=usage)
S0C、S1C:第一、二个幸存区的大小
S0U、S1U:第一、二个幸存区的使用大小
EC、EU:伊甸区容量以及使用大小
OC、OU:老年代容量以及使用大小
MC:元数据空间大小
MU:元数据使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC、 YGCT:年轻代垃圾回收次数、消耗时间
FGC、FGCT:老年代full GC垃圾回收次数、消耗时间
GCT:垃圾回收消耗总时间
查看gc原因
#通过gccause查看GC原因,1000毫秒执行一次输出
jstat -gccause pid 1000
[root@ahuang ~]# jstat -gccause 14074 1000
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC
0.00 0.00 1.91 13.74 94.54 91.59 59 0.689 4 1.161 1.850 Heap Inspection Initiated GC No GC
0.00 0.00 1.91 13.74 94.54 91.59 59 0.689 4 1.161 1.850 Heap Inspection Initiated GC No GC
后两行分别代表:LGCC(上一次GC的原因),GCC(最近一次GC的原因)。
例如:进行一次堆内存存活对象的查看( jmap -histo:live PID),然后执行gccause,可以看到具体原因是 Heap Inspection Initiated。其他原因列表请看这里
查看gc详细日志
GC日志有两种查看方式:
运行过程中通过jinfo命令查看
启动时设置参数
jinfo查看
通过jinfo在程序运行过程中查看
#step1:运行一个spring boot程序,分配256堆空间(配合本文开头的代码,多次调用)
nohup java -X