虽然Golang的GC自打一开始,就被人所诟病,但是经过这么多年的发展,Golang的GC已经改善了非常多,变得非常优秀了。

以下是Golang GC算法的里程碑:

v1.1 STW

v1.3 Mark STW, Sweep 并行

v1.5 三色标记法

v1.8 hybrid write barrier

经典的GC算法有三种: 引用计数(reference counting) 、 标记-清扫(mark & sweep) 、 复制收集(Copy and Collection) 。

Golang的GC算法主要是基于 标记-清扫(mark and sweep) 算法,并在此基础上做了改进。因此,在此主要介绍一下 标记-清扫(mark and sweep)算法 ,关于 引用计数(reference counting) 和 复制收集(copy and collection) 可自行百度。

标记-清扫(Mark And Sweep)算法

此算法主要有两个主要的步骤:

标记(Mark phase)

清除(Sweep phase)

第一步,找出不可达的对象,然后做上标记。

第二步,回收标记好的对象。

操作非常简单,但是有一点需要额外注意: mark and sweep 算法在执行的时候,需要程序暂停!即 stop the world 。

也就是说,这段时间程序会卡在哪儿。故中文翻译成 卡顿 。

我们来看一下图解:

开始标记,程序暂停。程序和对象的此时关系是这样的:

然后开始标记,process找出它所有可达的对象,并做上标记。如下图所示:

标记完了之后,然后开始清除未标记的对象:

然后 垃圾 清除了,变成了下图这样。

最后,停止暂停,让程序继续跑。然后循环重复这个过程,直到 process 生命周期结束。

标记-清扫(Mark And Sweep)算法存在什么问题?

标记-清扫(Mark And Sweep)算法 这种算法虽然非常的简单,但是还存在一些问题:

STW,stop the world;让程序暂停,程序出现卡顿。

标记需要扫描整个heap

清除数据会产生heap碎片

这里面最重要的问题就是:mark-and-sweep 算法会暂停整个整个程序。

Go是如何面对并这个问题的呢?

三色并发标记法

我们先来看看Golang的三色标记法的大体流程。

首先:程序创建的对象都标记为白色。

gc开始:扫描所有可到达的对象,标记为灰色

从灰色对象中找到其引用对象标记为灰色,把灰色对象本身标记为黑色

监视对象中的内存修改,并持续上一步的操作,直到灰色标记的对象不存在

此时,gc回收白色对象。

最后,将所有黑色对象变为白色,并重复以上所有过程。

好了,大体的流程就是这样的,让我们回到刚才的问题:Go是如何解决 标记-清除(mark and sweep) 算法中的卡顿(stw,stop the world)问题的呢?

gc和用户逻辑如何并行操作?

标记-清除(mark and sweep)算法的STW(stop the world)操作,就是runtime把所有的线程全部冻结掉,所有的线程全部冻结意味着用户逻辑是暂停的。这样所有的对象都不会被修改了,这时候去扫描是绝对安全的。

Go如何减短这个过程呢?标记-清除(mark and sweep)算法包含两部分逻辑:标记和清除。

我们知道Golang三色标记法中最后只剩下的黑白两种对象,黑色对象是程序恢复后接着使用的对象,如果不碰触黑色对象,只清除白色的对象,肯定不会影响程序逻辑。所以: 清除操作和用户逻辑可以并发。

标记操作和用户逻辑也是并发的,用户逻辑会时常生成对象或者改变对象的引用,那么标记和用户逻辑如何并发呢?

process新生成对象的时候,GC该如何操作呢?不会乱吗?

我们看如下图,在此状态下:process程序又新生成了一个对象,我们设想会变成这样:

但是这样显然是不对的,因为按照三色标记法的步骤,这样新生成的对象A最后会被清除掉,这样会影响程序逻辑。

Golang为了解决这个问题,引入了 写屏障 这个机制。

写屏障:该屏障之前的写操作和之后的写操作相比,先被系统其它组件感知。

通俗的讲:就是在gc跑的过程中,可以监控对象的内存修改,并对对象进行重新标记。(实际上也是超短暂的stw,然后对对象进行标记)

在上述情况中, 新生成的对象,一律都标位灰色!

即下图:

那么,灰色或者黑色对象的引用改为白色对象的时候,Golang是该如何操作的?

看如下图,一个黑色对象引用了曾经标记的白色对象。

这时候,写屏障机制被触发,向GC发送信号,GC重新扫描对象并标位灰色。

因此,gc一旦开始,无论是创建对象还是对象的引用改变,都会先变为灰色。

参考文献:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

go java gc_图解Golang的GC垃圾回收算法相关推荐

  1. GC垃圾回收算法三种方式

    收 旧对象,破 对象,用不着的对象,用旧对象 .破对象 .用不着 的 对 象换 盆,换大铝盆,换各种盆...............啊哈哈哈是不是脑袋自动播放了...皮一下 1.判定对象存活算法 在回 ...

  2. java golang gc_Golang GC 垃圾回收机制详解

    摘要 在实际使用 go 语言的过程中,碰到了一些看似奇怪的内存占用现象,于是决定对go语言的垃圾回收模型进行一些研究.本文对研究的结果进行一下总结. 什么是垃圾回收? 曾几何时,内存管理是程序员开发应 ...

  3. Java虚拟机(十四)——垃圾回收算法

    文章目录 垃圾回收相关算法 标记阶段 引用计数算法 可达性分析算法(根搜索算法.追踪性垃圾收集) 基本思路: GC Roots 有哪几类? 注意 对象的finalization机制 清除阶段 标记-清 ...

  4. JVM内功心法-GC垃圾回收之GC垃圾回收过程

    JVM内功心法-GC垃圾回收之GC垃圾回收算法 GC 全称garbagecollection,垃圾回收.JAVA 为了屏蔽操作系统和平台之间的差异.选择的是采用 java 虚拟机来运行 java 应用 ...

  5. 【JVM从小白学成大佬】4.Java虚拟机何谓垃圾及垃圾回收算法

    在Java中内存是由虚拟机自动管理的,虚拟机在内存中划出一片区域,作为满足程序内存分配请求的空间.内存的创建仍然是由程序猿来显示指定的,但是对象的释放却对程序猿是透明的.就是解放了程序猿手动回收内存的 ...

  6. 【Android 内存优化】内存抖动 ( 垃圾回收算法总结 | 分代收集算法补充 | 内存抖动排查 | 内存抖动操作 | 集合选择 )

    文章目录 一. 垃圾回收算法总结 二. 分代收集算法补充 三. 查看 Java 虚拟机 四. 获取 Android 应用可使用最大内存 五. 内存抖动标志 六. 排查内存抖动 七. 常见的造成内存抖动 ...

  7. 垃圾回收算法与垃圾回收器

    Java与C++等语言最大的技术区别:自动化的垃圾回收机制(GC) 为什么要了解GC和内存分配策略 1.面试需要 2.GC对应用的性能是有影响的: 3.写代码有好处 栈:栈中的生命周期是跟随线程,所以 ...

  8. 中断挂起是什么意思_深入JVM(三)- 什么是垃圾及垃圾回收算法

    1 垃圾回收 在堆里面存放着Java世界中几乎所有的对象实例,垃圾收集器在堆进行回收前,第一件事就是要确定这些对象之中哪些还"存活"着,哪些已经"死亡"(即不可 ...

  9. 图解Golang的GC算法

    图解Golang的GC算法 原创 RyuGou 程序猿菜刚RyuGou 2019-03-10 来源:https://mp.weixin.qq.com/s/_h0-8hma5y_FHKBeFuOOyw ...

最新文章

  1. CV领域中的Bert,了解一下?
  2. 梯度消失问题学习资料整理
  3. angular微信支付实际url地址不同
  4. 农业银行联行号怎么查询_农行信用卡解析丨菜卡怎么提额8W?学会一招就够了!...
  5. 前端学习(1166):扩展运算符02
  6. 极光推送 android 最新,Android——快速集成极光推送-Go语言中文社区
  7. 微软 CEO 萨提亚·纳德拉:不要重复造轮子,提升技术强密度
  8. ftp4j的android应用
  9. 动物行为检测计算机视觉_当动物行为研究遇见机器视觉——“红外热成像+计算机视觉”动物行为研究系统...
  10. SOA平台之争:Java EE,还是.NET……
  11. 怎样测试企业级SSD
  12. 1292:宠物小精灵之收服
  13. 吃饭 睡觉 打豆豆!!!
  14. 数据湖:数据同步工具NiFi
  15. 百度App Android启动性能优化-工具篇
  16. 实验改变人类:震撼世界的十大科学实验- -
  17. ORA-12541: TNS:no listener 解决办法
  18. 适用于XP的AMD双核优化补丁集
  19. htonl, ntohl两种实现
  20. 詹姆斯谈绝杀:确保不给对手留时间

热门文章

  1. java中start与loop_java for-loop问题
  2. mysql 时间 设计模式_数据库时间设计模式
  3. 使用一个环境的或者半径异样消除器来进行异样消除
  4. db2导入发生错误显示不是绝对路径_python编程常见错误总结
  5. Windows10配置CUDA10.0+cudnn7.5.1
  6. 基础功能-tensorflow使用gpu
  7. 【使用指南】WijmoJS 前端开发工具包
  8. MyBatis核心接口和类
  9. 数据库设计五要点 让数据库设计更加规范
  10. 在visual studio 2010+中调用ffmpeg编译时 报错error LNK xxxx: 模块对于 SAFESEH 映像是不安全的。...