GC日志分析
通过阅读GC日志,我们可以了解java虚拟机内存分配回收策略,内存分配与垃圾回收的参数列表
- -XX:+PrintGC 输出GC日志 类似-verbose:gc
- -XX:+PrintGCDetails 输出GC详细日志
- -XX:+PrintGCTimestamps 输出GC时间戳 (以基准时间的形式)
- -XX:+PrintGCDatestamps 输出GC日期时间戳 (以日期的形式,如2013-05-04T21:53:59.234+0800)
- -XX:+PrintHeapAtGC 在进行GC前后打印堆信息
- -Xloggc:./log/to/gc.log GC日志文件输出路径
Verbose:gc
参数解析
-XX:+PrintGCDetails
输入信息如下
参数解析
- GC和FullGC说明了这次垃圾收集器的停顿类型,如果有Full则说明GC发生了STW
- 使用Serial收集器在新生代的名称是Default New Genreation 因此显示的是DefNew
- 使用ParNew收集器在新生代的名称为变成ParNew parallel new genration
- 使用Pallel scavenge 收集器在新生代的名字是 PSYoungGen
- 老年代收集和新生代道理一样,名字也是收集器决定
- 使用G1收集会显示为garbage-frist heap
Allocation Failure表明本次引起GC的原因是因为在新生代中没有足够的空间能存储新的数据了
[PSYoungGen:5986K->696K(8704K)]5986K->704K(9216K)中括号内:GC回收前年轻代大小,回收后大小,(年轻代总大小)括号外:GC回收前年轻代和老年代大小,回收后大小,(年轻代和老年代总大小)
user代表用户态回收耗时,sys内核态回收耗时,real实际耗时。由于多核的原因,时间总和可能会超过real时间
Young GC图片
FullGC图片、
GC回收举例
我们编写一个程序,用来说明GC收集的过程
public class GCUseTest {
static final Integer _1MB = 1024 * 1024;
public static void main(String[] args) {
byte [] allocation1, allocation2, allocation3, allocation4;
allocation1 = new byte[2 *_1MB];
allocation2 = new byte[2 *_1MB];
allocation3 = new byte[2 *_1MB];
allocation4 = new byte[4 *_1MB];
}
}
我们设置JVM启动参数
-Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
首先我们会将3个2M的数组存放到Eden区,然后后面4M的数组来了后,将无法存储,因为Eden区只剩下2M的剩余空间了,那么将会进行一次Young GC操作,将原来Eden区的内容,存放到Survivor区,但是Survivor区也存放不下,那么就会直接晋级存入Old 区
然后我们将4M对象存入到Eden区中
GC日志分析工具
常用的日志分析工具有:GCViewer、GCEasy、GCHisto、GCLogViewer、Hpjmeter、garbagecat等
GCViewer
GC easy