JVM之垃圾回收算法详解

  • 现有的垃圾回收算法
    • 分类
    • 垃圾收集器的设计原则
    • 标记-清除算法
      • 缺点
    • 标记-复制算法
      • “Apple回收策略”
      • 缺点
    • 标记-整理算法
      • 缺点
    • 总结

现有的垃圾回收算法

分类

根据如何判定对象是垃圾,垃圾回收算法分为两类:
1、引用计数式垃圾收集(判定垃圾是通过引用计数器)别名:直接垃圾收集
2、追踪式垃圾收集(判定垃圾是通过GC Roots)别名:间接垃圾收集

主流虚拟机采用的是第二种追踪式垃圾收集,所以本文讲解第二种垃圾收集的算法

垃圾收集器的设计原则

根据两个分代假说:

1.绝大部分对象是熬不过第一次垃圾回收的
2.熬过多次垃圾回收的对象是难以被标记为垃圾的。

垃圾收集器将堆中的内存划分为了不同的区域,根据对象分代年龄(熬过多少次垃圾回收)来分配到不同的区域中:

比如对象分代年龄小的,第一种对象就应该标记存活对象即可,而不需要标记那些垃圾对象,因为这部分对象大部分都是很快用完就不用的垃圾对象。

而第二种对象分代年龄大的,则应该标记的是垃圾对象,因为根据第二个假说这部分对象中垃圾对象的占比很少,所以垃圾回收的频率也可以降低。

将堆划分为不同的区域后,垃圾回收器可以只回收其中一部分区域,针对每一部分区域也可以采用不同的算法来进行回收垃圾。

一般来说堆中至少会被划分为“新生代”和“老年代”两个区域。新生代存储第一种假说类型的对象,老年代存放第二种假说类型的对象。

注意:这种设计看起来是完美的,但是如果老年代中的对象引用了新生代中的对象这个时候年轻代发生垃圾回收时,除了需要遍历GC Roots外,还需要遍历整个老年代才会确保年轻代中的对象真正没有对象引用。显然这种遍历整个老年代效率肯定会很低,所以采用了一种解决方案:读者有兴趣可以看看: 在这篇博客的末尾

标记-清除算法

最早出现的垃圾回收算法,之后出现的算法都是根据其缺点来进行演进的。

两个阶段:
1.标记
2.清除
标记需要回收的对象完成后进行统一回收所有被标记的对象,
也可以标记存活的对象统一回收没有被标记的对象。

一,标记
如何判定对象是否是垃圾的过程在上一篇 博客 中已经讲解过,接着标记这些垃圾对象。

二,清除
进行统一回收掉标记的对象。

缺点

1.当堆中的对象大部分是垃圾时,标记和清除的效率会变低,而且会随着内存中垃圾对象的增长,导致效率越来越低。

2.内存碎片化:因为内存分配不是连续的,所以当清除后,内存中会存在大量内存碎片。当遇到大对象分配内存找不到足够的连续的内存来存放时会提前触发GC。

标记-复制算法

采用的是“半区复制”的算法来实现的,即每次只使用其中的一部分内存,当这部分内存用完后将存活着的对象复制到另外一块内存上,接着清空刚才使用的那部分内存,当另一部分内存满了的时候再用上一次清空后的那块内存往复。

解决了标记-清除的内存碎片化问题,因为当发生GC时会进行全部清空,只将存活对象复制到另外一块内存中。

“Apple回收策略”

Andrew Appel针对刚刚分代假说中的第一条,提出了“Appel式回收策略”。

一般情况下百分之九十八的对象在经历第一次gc时就会被清除。因此做出优化将年轻代分为了一块eden空间和两块Survival空间。enen和Survival内存占比为8:1,即每次使用百分之九十的内存,只有百分之十的内存会被浪费,因为对象大部分都会死去所以没有必要分配一半的空间来存放存活对象。

但是如果使用百分之十的内存来存放存活对象,当存活对象在Survival空间存放不下时,这个时候就需要用老年代担保,因此当存不下时会存放到老年代中。

缺点

1.当内存中的对象存活率较高时,复制大量存活对象会使得效率变低。
2.如果不想造成严重的内存浪费,就需要有额外的空间进行分配。

标记-整理算法

上面所说的标记-复制算法针对与新生代中进行的回收算法,并不适用与老年代,原因:老年代中存活率较高,存放不下时需要额外的内存空间担保。

因此出现了标记-整理算法,
和标记-复制算法相同的是:标记的都是存活对象;
和标记-复制算法不同的是:复制算法将存活对象复制到另外一块内存上然后清除之前使用的内存,而整理算法是移动存活的对象到一端,然后清除边界以外的内存。

缺点

移动存活对象
对于老年代中GC之后大部分都为存活对象,将这些对象都进行移动并且更新引用这些对象的地方是一个比较耗时的操作。而且更新引用需要暂停用户线程来保证用户线程访问对象不会出错,简称STW,“Stop the Word”。

其实不止整理算法里面移动对象更新引用需要STW,清除算法和复制算法中的标记清除都需要STW,只不过时间短

总结

采用标记-整理算法意味着GC的时候要移动对象更新对象的引用,也就是说内存回收的时候会更复杂。

采用标记-清除算法意味着内存碎片化。

采用标记-复制算法意味着内存可用度不高。

“吞吐量”:赋值器(使用垃圾回收器的线程也就是用户线程)与垃圾回收器的效率总和。

因为内存分配和访问(内存碎片化导致过多的分配和访问)比垃圾回收器回收的频率(回收时需要STW,而且比较耗时)要高,因此整理这种方式其实吞吐量要比清除要好。

对于关注吞吐量的收集器Parallel Scabenge基于标记-整理算法,
对于关注STW的收集器CMS来说采用的是标记-清除算法。
其实CMS是一种将两种算法混合起来的收集器,大部分时间采用清除算法,只有当分配内存不足(碎片化特别严重)时用整理算法进行一次收集。

JVM之垃圾回收算法详解相关推荐

  1. JVM底层原理+四大垃圾回收算法详解-周阳老师

    转载自,感谢原作者:https://www.jianshu.com/p/9e6841a895b4 注意:垃圾回收算法周阳老师讲的有错误,具体在p19,四大垃圾回收算法为复制算法.标记-整理算法.标记- ...

  2. jvm垃圾回收算法详解

    前言 相比C语言,JVM虚拟机一个优势体现在对对象的垃圾回收上,JVM有一套完整的垃圾回收算法,可以对程序运行时产生的垃圾对象进行及时的回收,以便释放JVM相应区域的内存空间,确保程序稳定高效的运行, ...

  3. Java垃圾回收算法详解

    1 概述 在前一篇文章中讲到了Java虚拟机的基础知识和运行时数据区的划分,在运行时数据区的划分中,可分为线程共享区域和线程私有区域,而Java的垃圾回收就发生在线程共享区域中,更直观的说法就是Jav ...

  4. 【JVM基础】垃圾回收算法详解(引用计数、标记、清除、压缩、复制)

    前言 笔记参考 Java 全栈知识体系.星羽恒.星空茶 文章目录 前言 垃圾回收概述 引用计数法 案例 优点 缺点 标记.清除.压缩 标记 清除 压缩 标记清除算法 优点 缺点 标记压缩算法 优点 缺 ...

  5. JVM的垃圾回收机制详解和调优

    1.JVM的gc概述 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc都使用类似的 ...

  6. JVM 架构解释 + 垃圾回收机制 详解(基于JDK8版本)

    文章目录 1. JVM 内存结构 2. JVM 之 堆 3. JVM 之 垃圾回收器(GC, Garbage Collector) 3.1 垃圾回收器 分类 + 组合方式 3.2 年轻代的 垃圾处理器 ...

  7. go语言垃圾回收机制详解

    Golang GC 垃圾回收机制详解 独一无二的小个性 https://blog.csdn.net/u010649766/article/details/80582153 摘要 在实际使用 go 语言 ...

  8. python内存的回收机制_python的内存管理和垃圾回收机制详解

    简单来说python的内存管理机制有三种 1)引用计数 2)垃圾回收 3)内存池 接下来我们来详细讲解这三种管理机制 1,引用计数: 引用计数是一种非常高效的内存管理手段,当一个pyhton对象被引用 ...

  9. 第十五章: 菱悦 -垃圾回收GC详解

    第 15章 垃圾回收GC详解 文章目录 第 15章 垃圾回收GC详解 1.System.gc() 的理解 1.1.System.gc() 方法 1.2.不可达对象回收行为 2.内存溢出与内存泄漏 2. ...

最新文章

  1. 可视化解释11种基本神经网络架构
  2. 一行 Python 实现并行化 -- 日常多线程操作的新思路 - 左手键盘,右手书 - SegmentFault...
  3. CentOS 7.x自定义开机启动设置
  4. 苏宁大调整中的三个关键
  5. Scala 执行流程分析
  6. Python 中的万能之王 Lambda 函数
  7. 小程序引入的echarts过大如何解决_解决生鲜行业“获客难”的难题,教你如何妙用小程序...
  8. 冯长根教授:博士生其实不是学生
  9. GMTA的完整形式是什么?
  10. 华强北二手手机卖不出去,闲鱼砸一亿现金帮扶
  11. Kafka开发--C#生产和消费消息
  12. 数据库锁表的分析与解决
  13. 无限宽神经网络 - 神经网络正切核理论【NTK】
  14. 【开源微信】Java实现基于Redis公众号模板消息队列
  15. JavaWeb整合萤石云(一),VUE和小程序也适用
  16. 微信公众号平台登陆-你已授权登陆过XXXX
  17. 国内无代码平台数据统计功能对比
  18. 讯飞智能录音笔SR702让工作体验更佳
  19. 8421码,5421码,2421码和余3码的分类及转换
  20. SolidWorks焊件中将各结构构件分解成单个零件的方法

热门文章

  1. egret的eui.List滚动
  2. 2021-01-25 matlab2018a license manager error -8简单解决办法
  3. 使用精易模块取进程模块基地址-11111111111111111111
  4. Atom 下载、安装
  5. 点赞黄文仔董事长,为偏远地区教育助力
  6. 计算机设备租赁系统论文,设备租赁管理系统软件系统.doc
  7. html2canvas + jspdf 实现 html导出pdf
  8. APP如何进行性能测试?
  9. 破解ps dw al
  10. 纯文本还是HTML邮件