深入理解JVM学习笔记(二十六、JVM 内存分配----优先分配到eden&空间分配担保)

一、优先分配到eden

我们写一个程序来验证对象优先分配到eden,源码如下:

package com.zjt.test.jvm008;

public class Main {
	public static void main(String[] args) {
		byte [] b1 = new byte[4 * 1024 * 1024];
	}
}

 在运行main方法前进行如下配置,配置做用是让控制台显示JVM信息:

深入理解JVM学习笔记(二十六、JVM 内存分配----优先分配到eden&空间分配担保)_第1张图片

运行结果如下图所示:

深入理解JVM学习笔记(二十六、JVM 内存分配----优先分配到eden&空间分配担保)_第2张图片

从图中可以看出年轻代一共有38400K空间,6758K已经被使用。其中eden区被使用20%,其余区域使用率都是0。因此可以看出来 对象内存是有限分配至年轻代的eden区域的。

二、JVM对垃圾回收器的选择

仔细观察年轻代信息前方关键字是PSYoungGen。其中PS是指Parallel Scavenge,说明YoungGen使用的是Parallel收集器。而老年代中的PAROldGen说明老年代使用的是parnew收集器。

我们也可以用过配置来修改默认垃圾回收器。如下图所示:

深入理解JVM学习笔记(二十六、JVM 内存分配----优先分配到eden&空间分配担保)_第3张图片

 运行后结果如下图

深入理解JVM学习笔记(二十六、JVM 内存分配----优先分配到eden&空间分配担保)_第4张图片

 那么问题来了,为什么默认使用的是Parallel收集器呢,因为JVM内部机制判定当运行环境为Server环境时就使用Parallel收集器,而JVM对Server环境要求太低了,只需要2G+内存和多核CPU即可。因此绝大多数机器都会被JVM默认成Server环境。

查看自己环境也可以在CMD下执行java -version查看:

深入理解JVM学习笔记(二十六、JVM 内存分配----优先分配到eden&空间分配担保)_第5张图片

三、空间分配担保

我们按照下图要求对内存进行配置

深入理解JVM学习笔记(二十六、JVM 内存分配----优先分配到eden&空间分配担保)_第6张图片

配置如下图所示

深入理解JVM学习笔记(二十六、JVM 内存分配----优先分配到eden&空间分配担保)_第7张图片

我们在程序中定义四个对象,其中三个2M,一个4M。运行程序没查看GC显示。

程序如下:

package com.zjt.test.jvm008;

public class Main {
	public static void main(String[] args) {
		byte [] b1 = new byte[2 * 1024 * 1024];
		byte [] b2 = new byte[2 * 1024 * 1024];
		byte [] b3 = new byte[2 * 1024 * 1024];
		byte [] b4 = new byte[4 * 1024 * 1024];
                System.gc();
	}
}

GC显示如下图:

深入理解JVM学习笔记(二十六、JVM 内存分配----优先分配到eden&空间分配担保)_第8张图片

从上图可以看出。,eden中4M为我们程序中定义的最后一个对象,老年代占用的6M是我们先前定义的3个2M对象。下面我们分析下为什么会出现上图所示。

1、3个2M对象进入Eden,Eden使用了6M,剩余2M可用

2、一个4M对象进入Eden,Eden内存不够用,因此要进行GC,如下图

3、第二步要执行的GC会将对象往Survival区域放,因为新生代一共就10M,而Eden就用了8M。那两个Survival区域每个只有1M,这是放不下我们对象的。因此会触发空间分配担保策略。从老年代借用6M内存存放三个2M的对象。

 

 

你可能感兴趣的:(JVM)