文章目录

背景

JDK1.8 默认的垃圾回收器称为parallel
Scavenge,又称为并行垃圾清除收集器,该收集器是面向堆的大吞吐量要求而进行设计。该文通过实例代码,对parallel Scavenge进行实战解析。

JVM options设置

在idea->run-edit configuration中对VM options作以下配置:

JVM内存分配与回收策略的代码实战_jvm内存

  • Xms20M、-Xmx20M、-Xmn10M这三个参数限制了Java堆大小为20MB,不可扩展,其中10MB分配给新生代(eden space:8M,from space 1M, to space 1M),剩下的10MB分配给老年代。
  • -XX:+PrintGCDetails通过控制台输出收集器日志信息

编码

1、对象优先在Eden分配
/**
* jvm内存回收策略解析
*
* @author zhuhuix
* @date 2020-05-20
*/
public class Gc {

//JVM参数: -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8

//定义一个静态常量代表1M空间
public final static int M = 1024 * 1024;

public static void main(String[] args) {

byte[] memory1 = new byte[2 * M];
byte[] memory2 = new byte[2 * M];

}
}

新生代中总共分配为9M内存,使用了6M内存,老年代分配10M,使用0.

JVM内存分配与回收策略的代码实战_java_02

2、新生代转入老年代

Minor GC指发生在新生代的垃圾收集动作

/**
* jvm内存回收策略解析
*
* @author zhuhuix
* @date 2020-05-20
*/
public class Gc {

//JVM参数: -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8

//定义一个静态常量代表1M空间
public final static int M = 1024 * 1024;

public static void main(String[] args) {

byte[] memory1 = new byte[2 * M];
byte[] memory2 = new byte[2 * M];
byte[] memory3 = new byte[2 * M];
//触发一次Minor GC,新生代转入老年代
byte[] memory4 = new byte[4* M];

}
}

JVM内存分配与回收策略的代码实战_老年代_03

3、大对象直接进入老年代

对象内存分配超过eden space

/**
* jvm内存回收策略解析
*
* @author zhuhuix
* @date 2020-05-20
*/
public class Gc {

//JVM参数: -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8

//定义一个静态常量代表1M空间
public final static int M = 1024 * 1024;

public static void main(String[] args) {

byte[] memory1 = new byte[9 * M];


}
}

JVM内存分配与回收策略的代码实战_java_04

4、Full GC

Full GC主要指新生代、老年代、metaspace上的全部GC。

/**
* jvm内存回收策略解析
*
* @author zhuhuix
* @date 2020-05-20
*/
public class Gc {

//JVM参数: -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8

//定义一个静态常量代表1M空间
public final static int M = 1024 * 1024;

public static void main(String[] args) {

byte[] memory1 = new byte[2 * M];
byte[] memory2 = new byte[2 * M];
byte[] memory3 = new byte[2 * M];

//触发一次Minor GC,新生代转入老年代
byte[] memory4 = new byte[2* M];

//触发full GC,对内存进行回收
memory1=memory2=memory3=memory4=null;
memory1 = new byte[8*M];

}
}

JVM内存分配与回收策略的代码实战_jvm内存_05