Java 虚拟机 GC 的过程

Java 虚拟机 GC 的过程
1)大多数对象在创建后很短的时间内就会没有任何对象再使用它了,即未被其它对象引用。
2)大多数一直被使用的对象(老对象)很少引用新创建的对象。
绝大部分对象的创建后是被放到eden区,为什么说是绝大部分,因为会有一些对象创建后直接被old区区。
因为在eden区全部都是新生对象,所以大部分对象会很快失去引用 。被回收后会获得大量的空间。
当经历了一次回收后红色的被回收掉,蓝色的进入From区或者Survivor区。所以时候在该区域的对象至少经历过一次回收。
当第二次回收的时候,发现form区域一个对象失去引用,那么GC就将其回收。红色将被回收,蓝色存活。接着蓝色对象将会被复制到Survivor区域,然后清空from区域。
所以说在每一次回收以后Eden区是空的,from或Survivor区域有一个是空的。
在From和Survivor两个空间,每一次GC都是将一个区域存活的复制到另一个区域,然后将该区域的对象全部清除。来回往复。如果达到幸存次数的阈值,那么该对象将被移动到old区。
old区的对象就相对来说稳定了,不会出现eden区域的大面积死亡的情况。
因为在eden区和old区相比,old区域所占的内存空间肯定是最大的,一般都会比eden区域要大,因为得考虑到最坏的情况,在项目启动的时候所有的eden对象都被移动到了old区域。

下面介绍一下几种常用的回收算法:
1标记清除算法。
Java 虚拟机 GC 的过程
我们将失去引用的对象标记为,在图中为红色区域,标记之后将其GC,回收完的内存如右图。但是这样的弊端会导致内存中有碎片产生,导致可用的连续空间越来越少。
复制算法
上用于Eden区的From和Survivor区,将一个区域划分成两个区域,将没有失去引用的对象复制到另一个区域,然后清空该区域。获得更多的连续空间。

标记 - 整理算法

Java 虚拟机 GC 的过程

其实和标记清除算法基本一致,只不过在清理完成之后,将所有存活的对象都移动到一端,这样做的缺点就是会有复制的开销,但是每次清理后留下的都是连续的内存空间。