ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

GO语言GC的历史及演进简介

2022-01-27 11:32:39  阅读:192  来源: 互联网

标签:演进 回收 mark go GC 垃圾 版本 GO gc


go语言垃圾回收总体采用的是经典的mark and sweep算法。

  • 1.3版本以前,golang的垃圾回收算法都非常简陋,然后其性能也广被诟病:go runtime在一定条件下(内存超过阈值或定期如2min),暂停所有任务的执行,进行mark&sweep操作,操作完成后启动所有任务的执行。在内存使用较多的场景下,go程序在进行垃圾回收时会发生非常明显的卡顿现象(Stop The World)。在对响应速度要求较高的后台服务进程中,这种延迟简直是不能忍受的!这个时期国内外很多在生产环境实践go语言的团队都或多或少踩过gc的坑。当时解决这个问题比较常用的方法是尽快控制自动分配内存的内存数量以减少gc负荷,同时采用手动管理内存的方法处理需要大量及高频分配内存的场景。
  • 1.3版本开始go team开始对gc性能进行持续的改进和优化,每个新版本的go发布时gc改进都成为大家备受关注的要点。1.3版本中,go runtime分离了mark和sweep操作,和以前一样,也是先暂停所有任务执行并启动mark,mark完成后马上就重新启动被暂停的任务了,而是让sweep任务和普通协程任务一样并行的和其他任务一起执行。如果运行在多核处理器上,go会试图将gc任务放到单独的核心上运行而尽量不影响业务代码的执行。go team自己的说法是减少了50%-70%的暂停时间。
  • 1.4版本对gc的性能改动并不多。1.4版本中runtime很多代码取代了原生c语言实现而采用了go语言实现,对gc带来的一大改变是可以是实现精确的gc。c语言实现在gc时无法获取到内存的对象信息,因此无法准确区分普通变量和指针,只能将普通变量当做指针,如果碰巧这个普通变量指向的空间有其他对象,那这个对象就不会被回收。而go语言实现是完全知道对象的类型信息,在标记时只会遍历指针指向的对象,这样就避免了C实现时的堆内存浪费(解决约10-30%)。
  • 1.5版本go team对gc又进行了比较大的改进(1.4中已经埋下伏笔如write barrier的引入),官方的主要目标是减少延迟。go 1.5正在实现的垃圾回收器是“非分代的、非移动的、并发的、三色的标记清除垃圾收集器”。分代算法上文已经提及,是一种比较好的垃圾回收管理策略,然1.5版本中并未考虑实现;我猜测的原因是步子不能迈太大,得逐步改进,go官方也表示会在1.6版本的gc优化中考虑。同时引入了上文介绍的三色标记法,这种方法的mark操作是可以渐进执行的而不需每次都扫描整个内存空间,可以减少stop the world的时间。 由此可以看到,一路走来直到1.5版本,go的垃圾回收性能也是一直在提升,但是相对成熟的垃圾回收系统(如java jvm和javascript v8),go需要优化的路径还很长
  • GO v1.5-v1.7三色标记法+开启写屏障

  • Go v1.8三色标记法+结合写屏障和删除屏障的混合写屏障法

     

标签:演进,回收,mark,go,GC,垃圾,版本,GO,gc
来源: https://www.cnblogs.com/linhaifeng/p/15849233.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有