Java的垃圾回收算法

    Java语言规范没有明确地说明JVM使用哪种垃圾回收算法,但是任何一种垃圾回收算法一般要做2件基本的事情:

1)发现无用信息对象;

2)回收被无用对象占用的内存空间,使该空间可被程序再次使用。

    本文只讨论垃圾回收算法,对如何判断对象是可被回收的感兴趣请参考可达性分析算法,对垃圾回收器感兴趣的具体收集器请参考垃圾回收器

1、标记-清除算法(Mark-Sweep)

    标记-清除算法是最基础的收集算法,后续的算法都是基于这种算法的思路并对其不足进行改进得到的。

    算法分为两个阶段:标记阶段和清除阶段。标记阶段是标记出所有需要回收的对象,清除阶段是标记完成后统一回收所有标记的对象。标记过程使用可达性分析算法。

    标记——清除算法的缺点:

1)效率问题,标记和清除两个过程效率都不高;

2)空间问题,标记清除后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后程序运行过程中需要分配较大对象时,无法找到足够连续的内存而不得不提前触发另一次垃圾收集动作。

2、复制算法(copying)

    该算法的提出是为了解决标记-清除算法的空间问题。

    算法开始时把堆分成一个对象面和多个空闲面,程序从对象面为对象分配空间,当对象满了,基于复制算法的垃圾收集就扫描活动对象,并将活动对象复制到空闲面,这样空闲面变成了对象面,原来的对象面变成了空闲面,程序会在新的对象面中分配内存。复制过程中用户程序暂停执行。

 

    复制算法的优点:实现简单,运行高效且不容易产生内存碎片;

    缺点:对内存空间的使用做出了高昂的代价,可用内存明显减少。

    算法的应用

    很明显,复制算法适用于内存中对象活率不高的情况。所以现在的商业虚拟机都采用这种收集算法来对新生代的垃圾回收。

3、标记-整理算法(Mark-Compact)

    标记-整理算法采用标记-清除算法一样的方式进行对象的标记,但在清除时不同,在回收不存活的对象占用的空间后,会将所有的存活对象往左端空闲空间移动,并更新对应的指针。

    标记-整理算法是在标记-清除算法的基础上,又进行了对象的移动,因此成本更高,但是却解决了内存碎片的问题。

    算法应用

    很明显,这种算法适用于被回收的对象比较少的情况。所以老年代一般会使用标记-整理算法来进行垃圾回收。

4、分代收集算法(Generational Collection)

    分代收集算法,更应该说是一种思想而不是具体的算法。这是一种JDK7中提出的、并被主流采用的一种垃圾收集思想。它基于这样一个事实:不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的回收算法,以便提高回收效率。

    在新生代每次垃圾回收都会有大批对象死去,只有少量存活,所以一般采取Copying算法,只需要采用少量存活对象的复制成本就可以完成收集;而老年代由于对象存活率高、没有额外空间进行分配担保,就必须使用标记-整理算法。

   另外,需要注意的是,在堆区之外还有一个“持久代”,它用来存储class类、常量、方法描述等。对持久代的回收主要回收两部分内容:废弃常量和无用的类。这个所谓的“持久带”,严格来说并不属于分代收集的范畴,因为它不属于堆内存。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值