GC中的算法学习

GC的四种算法

标记—清除法

实现过程
标记清楚法主要分为两个阶段:对对象的标记阶段和对对象的清除阶段。标记阶段会对全堆做一个遍历,给对象储存一个标记位标记上两种状态,分别是存活和死亡状态。然后在清除阶段对死亡的对象做统一清除。
优点
– 在遍历对象时只要找到该对象的一个引用时就可以判断它的状态。决定是否执行GC。
– 不用对对象移动,避免了复制操作。
缺点
–效率太低了,无论是标记还是清除都需要做递归和对全堆的遍历,这样的操作,算法复杂度太高了。
–没有整理对象的空间,会出现大量的碎片空间无法利用,造成空间的浪费。

标记—整理(压缩)算法

实现过程
是标记-清除算法的改良版。标记阶段同标记-清除算法一样,区别在于整理(压缩)阶段。遍历一块区域将存活的对象统一整理在另一块区域中,把原区域的剩余对象全部清除。
优点
因为它的整理(压缩)过程,不会出现碎片空间无法使用的情况。
缺点
如果存活的对象太多的话,整理阶段就需要做大量的复制移动操作。

复制算法

实现过程
将内存平均分为两个部分,每次只使用其中的一个模块,当这部分满的时候,就遍历将存活的对象放入另一内存中,将之前的内存空间全清。如此循环。
注意:与标记—整理不同的是,该算法不是在同一区域复制,而是有清楚的两块区域
优点
实现比较简单,不会出现内存碎片。
缺点
每次运行只能利用一般的内存空间。

分代收集算法

目前JVM最常用的垃圾回收方式,它根据对象的生命周期,将堆分为新生代和老年代。
新生代对象存活周期短,使用复制算法
老年代对象存活周期长,没有额外的空间进行分配担保,所以采用标记—清除算法或者标记—整理算法。

实现过程

新生代又分为Eden区 From区To区 空间比值是8:1:1

  1. 系统创建对象一般在Eden区操作,当Eden区满的时候触发一次Young GC操作(年轻代垃圾回收),此操作会把Eden区中存活的对象放到From区.

  2. 此时Eden区为空,当Eden区再次慢的时候,再触发Young GC操作,这个操作会将Eden与From区正在使用的对象统一放在To区中。

  3. 再一次YoungGC操作的时候,是将Eden区与To区中正在被使用的对象放在From区。

  4. 见过若干次这样的操作后,会发现有一部分一直存活得对象在From与To区之间游荡,这些对象会被转入到老年代。

  5. 老年代操作(标记-清除,标记-整理)几次后,空间被用完就会触发Full GC (集体清除)。注意:full GC 操作不能过于频繁,会对性能产生较大的影响。

上一篇:Minor GC的过程


下一篇:Java堆,新生代,老年代,永久代