Garbage Collection

1. 引用计数法(Reference Counting Collector)

作为早期策略。在这种方法中,堆中每个对象实例都有一个引用计数。当一个对象被创建时,且将该对象实例分配给一个变量,该变量计数设置为1。当任何其它变量被赋值为这个对象的引用时,计数加1。

优点:

  1. 执行速度比较快

缺点:

  1. 无法检测出循环引用

<br/>

2. 标记-清除算法

把所有的引用关系看作一张图,从GC ROOT开始,寻找对应的引用节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用的节点。

优点:

  1. 在存活对象比较多的情况下较为高效

缺点:

  1. 直接回收不存活的对象,因此会造成内存碎片。
  2. 不够高效

标记-整理算法(Mark-Compact) 与 标记-清除算法一样的方法,但是在回收不存活的对象占用空间后,会整理空闲空间,并更新指针。解决了内存碎片的问题,但是成本更高。

<br/>

3. Stop-and-Copy算法

它开始时把堆分成 一个对象面和多个空闲面,对象面用于分配空间,满了以后,GC从根集中扫描活动对象,并将每个活动对象复制到空闲面,这样空闲面变成了对象面。在对象面与空闲区域面的切换过程中,程序暂停执行。

<br/>

4. Generation算法

因为不同对象的生命周期不同,所以对于不同生命周期的对象使用不同的策略。

  1. Young Generation

    所有新生成的对象首先都是放在年轻代的。新生代发生的GC也叫做Minor GC,Minor GC发生频率比较高(不一定等Eden区满了才触发)。

  2. Old Generation

    在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。所以年老代存放的都是生命周期长的对象。内存也比新生代大很多。内存满的时候才会触发Full GC,发生频率较低。

  3. Permanent Generation

    用于存放静态文件,如类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate 等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。