Java 虚拟机 Jvm 堆内存分配

堆内存是 JVM 一块重点的区域,我们所说的 JVM 调优也是这一块。

1. 内存分配

在jdk1.7版本中堆内存被划分为三块:新生代、老年代、持久代。

新生代又主要分为:Eden区(伊甸园)、From Survivor区(幸存区0)、To Survivor区(幸存区1)。JVM默认分配空间为 8:1:1。也就是说Eden的空间分配是最大的。

2. 对象分配

我们新创建的对象实例首先会放在 新生代的Eden区(伊甸园)。

1.1. 大对象分配

我们也可以设置JVM参数将新创建对象实例放入老年代中。

虚拟机提供了一个-XX:PretenureSizeThreshold参数,令大于这个设置值的对象直接在老年代分配。

其目是为让新生代更好的运行。新生代采用的是复制算法下面会为大家讲述。

1.2. 新生代的运行

新创建的对象会放在Eden区(伊甸园),当Eden空间满了的时候会进行GC操作。称之为Minor GC。

1.Eden区(伊甸园)满了进行Minor GC进行空间清理死亡的对象。将Eden区(伊甸园)清理完后的对象复制到 S0(幸存者),S1为空。

2.当下一次 Eden 满了触发Minor GC时,清理Eden空间死亡对象,将存活对象复制到S1(幸存区)。同时,将清理S0(幸存区)空间死亡对象,将存活对象复制到S1。清空S0

Survivor区总有一个(幸存区)为空。

jvm给每个对象都分配了一个年龄,每次Minor GC对象就会+1。

jvm -XX:MaxTenuringThreshold 默认为15,也就是说对象年龄大于15就会进入老年代。我们也可以设置这个参数。

注意:当发生Minor GC的时候,发现Survivor空间不足,部分对象无法复制到Survivor区,虚拟机通过分配担保机制将这些对象提前转移到老年代。有兴趣可以看看这个担保机制。