VM参数:
1、在控制台打印出每次GC信息:
-XX:+PrintGCDetails
2、在发生OOM时打印出堆栈信息:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:\
发生OOM测试程序代码,也可以自行编写,运行VM参数(-Xms1m -Xmx1m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:\):
public class OOMDemo {
private static final int K = 1024;
private static final int M = K * K;
private static final int G = K * M;
private static final int ALIVE_OBJECT_SIZE = 32 * M;
public static void main(String[] args) {
int length = ALIVE_OBJECT_SIZE / 64;
ObjectOf64Bytes[] array = new ObjectOf64Bytes[length];
for (long i = 0; i < G; i++) {
array[(int) (i % length)] = new ObjectOf64Bytes();
}
}
}
class ObjectOf64Bytes {
long placeholder0;
long placeholder1;
long placeholder2;
long placeholder3;
long placeholder4;
long placeholder5;
}
Minor GC日志:
[GC --[PSYoungGen: 447K->447K(1024K)] 709K->956K(1536K), 0.0031459 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
下面来解析这一段信息,其实很简单,不用硬记,按顺序从左到右:
GC:表示这是发生了GC
PSYoungGen:GC类型,此处表示新生代内存发生了GC;
447K->447K:->前面的447K表示GC前新生代内存占用,->后面的447K表示GC后新生代内存占用(此处是分毫未被回收,那你执行个骡子,浪费 0.0031459秒);
(1024K):1024K表示新生代总共大小,看得出来是1M,可以回头看一下VM参数配置;
709K->956K:709K表示GC前JVM堆内存使用,956表示GC后JVM堆内存使用(硌老子的,GC后还变多了);
(1536K):1536K表示JVM堆内存总大小;
0.0031459 secs:本次GC耗时(看得出还是很快的);
user:GC用户耗时;
sys:GC系统耗时;
real:GC实际耗时。
Full GC日志:
[Full GC [PSYoungGen: 447K->197K(1024K)] [ParOldGen: 508K->494K(512K)] 956K->692K(1536K), [Metaspace: 3179K->3179K(1056768K)], 0.0069504 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Full GC:GC类型;
[PSYoungGen: 447K->197K(1024K)] :Young区,447K表示GC前Young区内存占用,197K表示GC后Young区内存占用,1024K表示Young区总大小;
[ParOldGen: 508K->494K(512K)] :Old区,508K表示GC前Old区内存占用,494K表示GC后Old区内存占用,512K表示Old区总大小;
956K->692K(1536K):956K表示GC前JVM堆内存使用,692K表示GC后JVM堆内存使用,1536K表示JVM堆内存总大小;
[Metaspace: 3179K->3179K(1056768K)]:元空间,3179K表示GC前后元空间的使用,1056768K表示元空间的总大小(使用VM参数 -XX:-UseCompressedClassPointers -XX:MetaspaceSize=50M指定元空间的总大小);
0.0069504 secs:本次GC耗时(看得出还是很快的);
user:GC用户耗时;
sys:GC系统耗时;
real:GC实际耗时。
规律:
[名称:GC前内存->GC后内存(总内存)]
Heap
PSYoungGen total 2560K, used 60K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000)
eden space 2048K, 2% used [0x00000000ffd00000,0x00000000ffd0f038,0x00000000fff00000)
from space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
to space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
ParOldGen total 7168K, used 736K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000)
object space 7168K, 10% used [0x00000000ff600000,0x00000000ff6b8128,0x00000000ffd00000)
Metaspace used 3328K, capacity 4112K, committed 4352K, reserved 8192K
解析上述:
PSYoungGen total = eden space + from space,内存地址eden+from+to
ParOldGen GC前后老年代的内存变化