简述:
垃圾回收算法有很多种,每种有各自的适用场合,各有千秋,如何在不同的场合搭配使用是我们要考虑的问题
引用计数
这是最简单最原始的算法。原理很简单,对象生成后,有一个相关联的计数器,当有一个地方引用时,计数器加1;当引用失效时,计数器减1。jvm定期扫描对象时,发现计数器为0的对象就可以清除。这个算法的特点是实现简单,速度快。不足之处在于:每次分配和指针操作都需要额外的操作来更新相关计数器。最大的问题是,循环引用的对象是永远没有办法被清除(avm就是这个算法,曾经是as3的码农深有体会)
根搜索算法
这里的根是一些特定的对象:虚拟机栈中引用的对象;方法区的类静态属性引用的对象;方法区中的常量引用的对象;本地方法栈中本地方法引用的对象。每次jvm扫描的时候,从这个根对象开始,有被引用的对象会被加入一条类似“引用链”。这里有点类似深度搜索算法。最后我们可以得出一张类似树形的引用链图。不在这个图的对象就可以清除了。这个算法的不足之处在于扫描时间可能比较长,尤其是引用关系比较复杂时
标记-清除(Mark-Sweep)
顾名思义,包括两个过程。在标记过程,就是采用上面描述的根搜索算法,如果被搜索到,可以在对象本身标记,或者额外记录那些数据被标记。清除的过程比较简单,jvm扫描所有对象,没有被标记的对象就被清除。可以用餐巾纸收集(来源见参考资料,下同)来描述。餐厅里,清洁工要清洁餐巾纸时,先暂停所有人,问每个人,用过那种餐巾纸,在该餐巾纸上做标记。然后清洁工就可以把那些没有被标记的餐巾纸回收了。这个算法有一些不足:效率不高;内存碎片问题。但是这个算法是最经典的垃圾回收算法,后来的很多算法都是在它的基础上改进的
复制算法
复制算法解决了标记-清除算法的效率问题。它的原理是,将内存区一分为二,每次只用其中一块,用完了,就将存活的对象直接拷贝到另外一块区域。这个过程只是移动堆顶指针,不产生内存碎片。很明显,最大的缺点是可以内存少了一半啊。再套用餐巾纸的例子:餐厅里面有两个大厅,大伙现在一个大厅吃饭,到了收垃圾时间了。清洁工让大伙带着正在用的餐巾到另外一个厅。接下来清洁工就可以安心清理无人使用的餐巾纸了。为了解决内存浪费的问题,HotSpot等采用了一个大区间Eden 和两个小区间Survivor From、To。每次回收时,将Eden和其中一个Survivor还存活的对象copy到另外一个Survivor,之后再清理剩下的不再引用的对象。Eden和Survivor的比率通常是8:1,所以只浪费了10%的空间
标记-整理(Mark-Compact)
这个算法是将标记-整理和复制算法的完美结合。同样分两个阶段,标记阶段跟标记-整理算法的标记过程一样。接下来是对复制算法的改进了。不用分成两个区了,而是将被标记的对象向一边移动,未被标记的对象向另外一端移动。最后再收集那些未被标记的对象。再用餐巾纸的例子来说明:第一步同样是对餐巾纸进行标记,接下来清洁工大妈命令所以的就餐者带上被标记的餐巾纸滚到一个角落,顺便把那些没有标记的餐巾纸扔到另外一个角落。大妈就轻松跑到那个角落,轻松搞定那些未被标记的餐巾纸。
增量收集
上面描述的算法都需要暂停程序的执行。增量收集是将传统的垃圾收集算法多进程(或线程)化。这里的难点是:标记过程结束后,执行程序可以又使对象“复活”。
分代收集
这个算法其实是基于数理统计的。不同的对象使用情况可能不同,有些瞬间消逝,有些恒久保留。为此,我们可以建立不同的区间,当对象经过n次考验,依然存活,就将它移到另外一个区域。现代的jvm就是采用了这个思想,分为新生代,持久代。每个区域可以根据情况,采用不用的垃圾收集算法。
参考资料
1.深入java虚拟机
2.深入理解java虚拟机
3.通俗解释垃圾回收算法 http://www.game798.com/html/2007-04/3425.htm
更多关于jvm的内容可以访问 www.iamcoding.com
分享到:
相关推荐
从JVM内存模型、常用JVM参数、垃圾回收算法和垃圾回收器等几个角度学习JVM
自己总结的jvm中垃圾回收相关算法的笔记,绘制了详细的思维导图,每个思维导图中均有详细的博文解释,方便大家学习和理解,免费分享给大家。适合jvm的爱好者和学习者
包括jvm 的内存模型 对象的创建过程 垃圾回收算法 垃圾回收器 内存分配和回收策略
Java是一种高性能、跨平台的面向...自动内存管理(垃圾回收): Java具有自动内存管理机制,通过垃圾回收器自动回收不再使用的对象,使得开发者不需要手动管理内存,减轻了程序员的负担,同时也减少了内存泄漏的风险。
Java是一种高性能、跨平台的面向...自动内存管理(垃圾回收): Java具有自动内存管理机制,通过垃圾回收器自动回收不再使用的对象,使得开发者不需要手动管理内存,减轻了程序员的负担,同时也减少了内存泄漏的风险。
Java是一种高性能、跨平台的面向...自动内存管理(垃圾回收): Java具有自动内存管理机制,通过垃圾回收器自动回收不再使用的对象,使得开发者不需要手动管理内存,减轻了程序员的负担,同时也减少了内存泄漏的风险。
答:启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。 40.接口是否可...
GC(垃圾回收算法) JVM性能监控和故障定位 JVM调优 JavaWeb servlet request response cookie && session 基础框架 SpringMVC Mybatis SpringBoot自动配置原理 安全框架 数据库 项目管理 Maven 其它 分布式
垃圾回收 类加载过程 类加载器 双亲委派 JVM性能调优监控工具 设计模式 消息中间件 RocketMQ 概念 RocketMQ 特性 RocketMQ 集群 RocketMQ 事务 RocketMQ 常见问题 数据库 Redis 基本数据结构 进阶使用 持久化 集群 ...
java8 源码 学习笔记(持续更新中) 所有文章均同步发布到微信公众号【JavaRobot】,关注微信公众号,及时得到文章推送,谢谢支持。 ...垃圾回收算法 JavaConcurrent(Java并发系列) 【Java并发系列】
向下,生动清晰阐述JVM原理,内存管理,垃圾回收算法,系统调用,多线程及各种锁实现源码分析,BIO/NIO/AIO到Netty源码原理,全程项目贯穿,推动理论实践,上课等于上班,经验超过传统教学后工作一年经验,夯实的...
曾经的我经常害怕处理内存溢出的问题,因为不知道他为什么会出现这个问题,当我在看了这本书以后明白了垃圾回收算法,以及JVM是如何帮助我们处理GC的,这个时候当出现这个问题的时候我就明白需要查找GC Root,或者...