垃圾回收算法

1、引用计数法(Reference Counting

        实现简单,为每个对象配备一个整型的引用计数器,只要有任何对象引用了该对象,该对象引用计数器的值加1,引用失效,则计数器的值减1。只要对象的引用计数器的值为0,该对象就不再被使用。

        缺点是无法处理循环引用的情况,且每次引用产生和消除时,需要执行加法和减法操作,影响系统性能。因此Java回收器没有使用引用计数法。

2、标记清除法(Mark-Sweep)

        标记阶段,标记所有从根节点可达的对象,清除阶段,清除所有未被标记的对象。

        缺点是回收后的空间是不连续的,会产生大量的内存碎片。

3、复制算法(Copying)

        适用于新生代,将原有的内存空间均分为两块,每次只使用其中一块,垃圾回收时,将正在使用内存中的存活对象复制到未使用的内存中,清空正在使用的内存,交换两个内存的角色,完成垃圾回收。如果系统中垃圾对象很多,需要复制的存活对象就会较少,真正垃圾回收时复制算法的效率就会很高。且存活对象统一被复制到新的内存空间,因此没有内存碎片。

        缺点是会将系统内存折半。

        在Java的新生代串行垃圾回收器中,使用了复制算法的思想。

        垃圾回收时,eden空间中的存活对象会被复制到未使用的survivor空间中(假设是to),正在使用的survivor空间(假设是from)中的年轻对象也会被复制到to空间中(大对象、或者老年对象会直接进入老年代,如果to空间已满,则对象也会直接进入老年代),然后清空eden和from空间即可。 

4、标记压缩法(Mark-Compact)

        适用于老年代,首先标记所有从根节点可达的对象,再将所有存活对象压缩到内存的一端,然后清理边界外所有的空间,即可完成回收。既避免了碎片的产生,又不会将内存折半。

         标记压缩法的最终效果等同于标记清除算法执行完成后,再进行一次内存碎片整理,因此也称为标记清除压缩(MarkSweepCompact)算法。

5、分代算法(Generational Collecting)

        根据对象生命周期的长短将内存区间分成新生代和老年代,每块使用不同的垃圾回收算法,提高垃圾回收效率。新生代对象的特点是对象朝生夕灭,90%的新建对象会很快被回收,因此适合使用复制算法。老年代中几乎所有的对象都是经过几次几次垃圾回收后依然存活的,这些对象在一段时期内都将常驻内存,如果使用复制算法将要复制大量的对象,因此老年代适合使用标记清除或标记压缩算法。

        新生代回收的频率高,但是每次回收的耗时短,老年代回收频率低,但是每次回收消耗的时间长。虚拟机使用一种叫做卡表(CardTable)的数据结构支持高频率的新生代回收,卡表是一个比特位集合,每一个比特位表示老年代某一区域中的所有对象是否持有新生代对象的引用。这样在新生代GC时,不用花大量时间扫描所有的老年代对象,来确定每一个对象的引用关系,而可以扫描卡表,只有卡表的标记位为1时,才扫描给定区域的老年代对象,卡表位为0所在区域的老年代对象一定不含有新生代对象的引用。

6、分区算法 (Region)

        将整个堆空间划分成连续的不同小区间,每个小区间独立使用、独立回收,从而可以控制一次回收多少个小区间。

        相同条件下,堆空间越大,一次GC需要的时间越长,产生的停顿也就越长。为了更好地控制GC产生的停顿时间,将一块大的内存区域分割成多个小块,根据目标停顿时间,每次合理的回收若干个小区间而不是整个堆空间,从而减少一次GC所产生的停顿。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值