深入理解JAVA虚拟机---GC日志详解

1.编写JAVA代码

import java.util.ArrayList;
import java.util.List;
/**
 * -verbose:gc -Xms30M -Xmx30M -Xmn10M -XX:PermSize=200M -XX:MaxPermSize=200M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:SurvivorRatio=8
 * @author Administrator
 *parallel Scanvenge
 */
public class HeapOutOfMemoryExample {

	public static void main(String[] args) {
		List<Object> list = new ArrayList<Object>();
		while(true) {
			list.add(new Object());
		}
		
	}

}

2.设置JVM参数

-verbose:gc -Xms30M -Xmx30M -Xmn10M -XX:PermSize=200M -XX:MaxPermSize=200M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:SurvivorRatio=8

《深入理解JAVA虚拟机---GC日志详解》

JVM参数说明

Xms=30M  //最小堆内存

Xmx=30M  //最大堆内存

Xmn=10M  //年轻代所占内存

PermSize=200M //永久代所占最小内存

MaxPermSize=200M  //永久代所占最大内存

SurvivorRatio=8   //年轻代中Eden区和Survivor区的比值

PrintGCDetails    //打印出垃圾回收日志

PrintGCDateStamps //打印出垃圾回收的时间

3.执行类HeapOutOfMemoryExample

打印出GC日志

《深入理解JAVA虚拟机---GC日志详解》

2017-11-22T22:36:06.735+0800: [GC [PSYoungGen: 7522K->1001K(9216K)] 7522K->5201K(29696K), 0.0087282 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2017-11-22T22:36:06.735+0800: [GC [PSYoungGen: 9193K->1024K(9216K)] 13393K->10990K(29696K), 0.0104110 secs] [Times: user=0.05 sys=0.00, real=0.02 secs] 
2017-11-22T22:36:06.751+0800: [Full GC [PSYoungGen: 9216K->0K(9216K)] [ParOldGen: 14714K->18607K(20480K)] 23930K->18607K(29696K) [PSPermGen: 2570K->2569K(204800K)], 0.2016436 secs] [Times: user=0.22 sys=0.00, real=0.20 secs] 
2017-11-22T22:36:06.953+0800: [Full GC [PSYoungGen: 5655K->4088K(9216K)] [ParOldGen: 18607K->20131K(20480K)] 24262K->24220K(29696K) [PSPermGen: 2569K->2569K(204800K)], 0.2352180 secs] [Times: user=0.33 sys=0.00, real=0.23 secs] 
2017-11-22T22:36:07.187+0800: [Full GC [PSYoungGen: 4088K->4088K(9216K)] [ParOldGen: 20131K->20120K(20480K)] 24220K->24209K(29696K) [PSPermGen: 2569K->2569K(204800K)], 0.1325484 secs] [Times: user=0.22 sys=0.00, real=0.14 secs] 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:2245)
	at java.util.Arrays.copyOf(Arrays.java:2219)
	at java.util.ArrayList.grow(ArrayList.java:242)
	at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:216)
	at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:208)
	at java.util.ArrayList.add(ArrayList.java:440)
	at com.HeapOutOfMemoryExample.main(HeapOutOfMemoryExample.java:15)
Heap
 PSYoungGen      total 9216K, used 4382K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
  eden space 8192K, 53% used [0x00000000ff600000,0x00000000ffa478e0,0x00000000ffe00000)
  from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
  to   space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
 ParOldGen       total 20480K, used 20120K [0x00000000fe200000, 0x00000000ff600000, 0x00000000ff600000)
  object space 20480K, 98% used [0x00000000fe200000,0x00000000ff5a6150,0x00000000ff600000)
 PSPermGen       total 204800K, used 2601K [0x00000000f1a00000, 0x00000000fe200000, 0x00000000fe200000)
  object space 204800K, 1% used [0x00000000f1a00000,0x00000000f1c8a418,0x00000000fe200000)

4.GC日志详解

2017-11-22T22:36:06.735+0800:[GC [PSYoungGen: 9193K->1024K(9216K)] 13393K->10990K(29696K), 0.0104110secs] [Times: user=0.05 sys=0.00, real=0.02 secs]

2017-11-22T22:36:06.735+0800 //垃圾回收时的时间        

GC //垃圾回收的类型,GC是只回收新生代;Full GC会回收新生代、年老代、永久代,会停止所有用户线程。

PSYoungGen  //年轻代的垃圾回收使用的是Parallel Scanvenge垃圾收集器,简称PS,年轻代就是PSYoungGen。

9193K->1024K(9216K)//年轻代划分成Eden区、From Survivor区和To Survivor区,整个年轻代可以用来使用的就是Eden区加上其中一个Survivor区,也就是8M+1M=9M=9216K,9193K是指Eden区+其中一个Survivor区在垃圾回收之前占用的内存,1024K是指Eden区+其中一个Survivor区在垃圾回收之后还在占用的内存

13393K->10990K(29696K)  //29696K指堆的可用大小,包含Eden区+其中一个Survivor区+年老代,8M+1M+20M=29M=29696K,13393K指执行垃圾回收前这三个区域所占的内存,10990K指执行垃圾回收之后这三个区域所占的内存。

Times:user=0.05 sys=0.00, real=0.02 secs //user=0.05是指CPU运行的总时长,如果有多核,则累加;sys=0.00,是指内核态消耗的CPU事时间;real=0.02是指操作从开始到结束所经过的墙钟时间,墙钟时间包括各种非运算的等待耗时,例如等待磁盘I/O,等待线程阻塞,而CPU时间不包括这些耗时。

2017-11-22T22:36:06.751+0800:[Full GC [PSYoungGen: 9216K->0K(9216K)] [ParOldGen:14714K->18607K(20480K)] 23930K->18607K(29696K) [PSPermGen:2570K->2569K(204800K)], 0.2016436 secs] [Times: user=0.22 sys=0.00,real=0.20 secs]

Full GC //垃圾回收的类型,GC是只回收新生代;Full GC会回收新生代、年老代、永久代,会停止所有用户线程。

ParOldGen   //年老代的垃圾回收采用的是ParNew收集器

14714K->18607K(20480K)   //20480K指年老代最大可以分配的内存20M=20480K;14714K指执行垃圾回收前永久代占用的内存;18607K指年老代执行垃圾回收后所占的内存,由于年轻代经过垃圾回收后年轻代或Survivor中的部分对象被移动到年老代,所以导致年老代执行垃圾回收后占用的内存超过垃圾回收之前所占的内存。

PSPermGen    //永久代的垃圾回收采用的是Parallel Scanvenge垃圾收集器

2570K->2569K(204800K)    //永久代最大可以分配的内存200M=204800K,2570K指永久代执行垃圾回收前所占内存,2569指永久代执行垃圾回收之后所占内存

Heap

 PSYoungGen      total 9216K, used 4382K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)

  eden space 8192K, 53% used [0x00000000ff600000,0x00000000ffa478e0,0x00000000ffe00000)

  from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)

  to   space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)

 ParOldGen       total 20480K, used 20120K [0x00000000fe200000, 0x00000000ff600000, 0x00000000ff600000)

  object space 20480K, 98% used [0x00000000fe200000,0x00000000ff5a6150,0x00000000ff600000)

 PSPermGen       total 204800K, used 2601K [0x00000000f1a00000, 0x00000000fe200000, 0x00000000fe200000)

  object space 204800K, 1% used [0x00000000f1a00000,0x00000000f1c8a418,0x00000000fe200000)

这是堆内存溢出时虚拟机打印出来的日志

PSYoungGen      total 9216K, used 4382K //指出现堆内存溢出时,Eden区+Survivor区可分配的内存总和是9216K,已经分配的内存是4382K

eden space8192K, 53% used //指Eden区可分配的内存总和8192K,已分配的内存占53%

from space1024K, 0% used //指from survivor区可分配的内存总和1024K,已分配的内存占0%

to space1024K, 0% used //指from survivor区可分配的内存总和1024K,已分配的内存占0%

ParOldGen       total 20480K, used 20120K //指年老代可分配的内存总和20480K,已分配的内存是20120K

objectspace 20480K, 98% used //指年老代中对象空间20480K,其中98%已用

PSPermGen       total 204800K, used 2601K //指永久代可分配的内存总和204800K,已分配的内存是2601K

object space 204800K, 1% used  //指永久代中对象空间20480K,其中98%已用

    原文作者:java虚拟机
    原文地址: https://blog.csdn.net/brushli/article/details/78609816
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞