一:如何分析GC日志?
二:如何通过工具进行分析运行中的系统?
三:常用的分析工具有哪些?
如何分析GC日志?
采用以下的JVM参数运行代码:
-XX:NewSize=5242880-【初始新生代大小】
XX:MaxNewSize=5242880-【最大新生代大小】
XX:InitialHeapSize=10485760-【初始堆大小】
XX:MaxHeapSize=10485760-【最大堆大小】
XX:SurvivorRatio=8-【新生代的分配比例】
XX:PretenureSizeThreashold=10485760-【大对象阈值】
XX:+UseParNewGC-
XX:+UseConcMarkSweepGC
JVM虚拟机内存分配图
如何打印出JVM日志?
需要在系统运行参数中配置如下参数:
1:-XX:+PrintGCDetails:打印详细的gc日志;
2:-XX:+PrintGCTimeStamps:这个参数可以打印出来每次GC发生的时间
3:-Xloggc:gc.log:这个参数可以设置将gc日志写入到磁盘文件
运行示例代码,分析GC运行情况
public class Demo1 {
public static void main(String[] args){
byte[] array1 = new byte[1024*1024];
array1 = new byte[1024*1024];
array1 = new byte[1024*1024];
array1 = null;
byte[] array2 = new byte[2*1024*1024];
}
}
0.187: [GC (Allocation Failure) 0.216: [ParNew: 3964K->512K(4608K), 0.0166086 secs] 3964K->543K(9728K), 0.0453090 secs] [Times: user=0.00 sys=0.00, real=0.05 secs]
0.187:系统运行多长时间发生了GC
ParNew:3964K->512K(4608K), 0.0166086 secs
3964K:GC之前新生代的对象大小
512K:GC之后存活的新生代对象大小
4608K:整个新生代的可用的内存大小(一个Eden+一个Survior)
0.0166086 secs :本次GC的耗时
3964K->543K(9728K)
9728K:整个堆内存的可用大小(新生代(一个Eden+一个Survivor)+老年代)
3964K:GC之前整个堆内存占用的大小
543K:GC之后整个堆内存占用的大小
Times: user=0.00 sys=0.00, real=0.05 secs
本次消耗的时间,精确到小数点后两位
从以上实例分析中的疑惑问题:
1:对于新生代发生GC之前占用的内存大小为3964K?
3*1024=3072<3964K ,除了我们创建的对象之外还存在一部分的未知对象占用内存
GC过后堆内存的使用情况
Heap
par new generation total 4608K, used 2601K [0x00000000ff600000, 0x00000000ffb00000, 0x00000000ffb00000)
eden space 4096K, 51% used [0x00000000ff600000, 0x00000000ff80a558, 0x00000000ffa00000)
from space 512K, 100% used [0x00000000ffa80000, 0x00000000ffb00000, 0x00000000ffb00000)
to space 512K, 0% used [0x00000000ffa00000, 0x00000000ffa00000, 0x00000000ffa80000)
concurrent mark-sweep generation total 5120K, used 31K [0x00000000ffb00000, 0x0000000100000000, 0x0000000100000000)
Metaspace used 2687K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 297K, capacity 386K, committed 512K, reserved 1048576K
par new generation total 4608K, used 2601K
4608K:新生代可用总大小
2601K:已占用内存大小
eden space 4096K, 51% used
from space 512K, 100%
to space 512K, 0%
concurrent mark-sweep generation total 5120K, used 31K 老年代内存使用情况
Metaspace used 2687K, capacity 4486K, committed 4864K, reserved 1056768K 元数据空间
class space used 297K, capacity 386K, committed 512K, reserved 1048576K Class空间
进入老年代常见的4个时机:
1:-XX:MaxTenuringThreshold=15,设置对象躲过多少次gc后进入老年代;
2:动态年龄判断规则,如果Survior区域内年龄1+年龄2+年龄3>=50%,将大于等于年龄3的存活的对象进入老年代;
3:gc之后存活的对象太多,无法放入Survior,此时直接进入老年代(如果From Survior可以放得下一部分的对象则,并不是所有的对象进入老年代);
4:-XX:PretenureSizeThreshold=10485760,大对象直接进入老年代;