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
2.设置JVM参数
-verbose:gc -Xms30M -Xmx30M -Xmn10M -XX:PermSize=200M -XX:MaxPermSize=200M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:SurvivorRatio=8
JVM参数说明
Xms=30M //最小堆内存
Xmx=30M //最大堆内存
Xmn=10M //年轻代所占内存
PermSize=200M //永久代所占最小内存
MaxPermSize=200M //永久代所占最大内存
SurvivorRatio=8 //年轻代中Eden区和Survivor区的比值
PrintGCDetails //打印出垃圾回收日志
PrintGCDateStamps //打印出垃圾回收的时间3.执行类HeapOutOfMemoryExample
打印出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)
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%已用