JVM学习笔记(三)JVM垃圾回收算法及内存分配策略

今天巩固并记录下JVM垃圾回收算法及内存分配策略。JVM将存储对象的内存分为两块---新生代和老年代。其中新生代使用的是复制算法而老年代使用的是标记-整理算法

复制算法

复制算法会将内存等量地分成两块,每次只使用其中的一块。当一块内存用完了就将还存活的对象复制到另一块上面之后将已使用过的内存清理掉。过程如下图:

JVM学习笔记(三)JVM垃圾回收算法及内存分配策略

新生代的内存会被分为两个区域---Eden区和Survivor区,每次都只使用Eden区和其中一块Survivor区。回收时将Eden区和Survivor区的存活对象复制到另一块Survivor然后对Eden区和Survivor区进行清理。

标记-整理算法

JVM老年代使用的是标记-整理算法。标记-整理算法是核心是首先标记需要回收的对象,然后将存活的对象都向一端移动然后清除该端边界之外的内存。过程如下图:

JVM学习笔记(三)JVM垃圾回收算法及内存分配策略

内存分配策略

大多数情况下,新对象会优先分配到Eden区。当Eden区没有足够的空间进行新对象的分配时,JVM会触发一次Minor GC (M inor GC 即发生在新生代的GC),若Eden区在GC后仍没有足够空间则考虑Survivor区,若Survivor区也没有足够空间则将存活的对象(新对象除外)直接放入老年代。对于需要大量连续内存存储空间的对象,也会直接分配至老年代。

为了标记对象是否能够进入老年代,JVM给每一个对象都定义了一个年龄计数器,当新生代进行一次Minor GC后,若Survivor内存足够,则将活下来的对象移动到Survivor区且年龄计数器数值+1。当年龄计数器数值达到一定数值(默认为15),该对象就会被分配至老年代。

对于对象来说,并非一定只有当年龄计数器达到阈值才能进入老年代。如果在Survivor空间中相同年龄的所有对象大小总和大于Survivor空间的一半,年龄大于等于该年龄的对象就可以直接进入老年代。