当前位置: 首页 > news >正文

Go进阶之垃圾回收

所谓垃圾就是不再需要的内存块.垃圾如果不清理就没办法再次分配使用,在不支持垃

圾回收的编程语言里.这些垃圾的内存就是泄漏的内存.

1.垃圾回收算法:

引用计数法:

对每个对象维护一个引用计数.当引用该对象的对象被销毁时.引用计数减一.当引用计

数器为0时回收该对象.

优点:

对象可以很快的被回收.不会出现内存耗尽或达到某个阈值时才回收.

缺点:

不能很好的处理循环引用.而且实时维护引用计数也有一定的代价.

标记-清除:

从根变量开始遍历所有引用的对象,引用对象标记为被引用,没有标记的对象被回收.

优点:

解决了引用计数的缺点.

缺点:

需要STW.暂时停止程序运行.

分代收集法:

按照对象的生命周期的长短划分为不同的代空间.生命周期长的放入老年代.而短的放

入年轻代.不同代有不同的算法和回收频率.

优点:

回收性能好.

缺点:

算法复杂.

2.Go垃圾回收:

垃圾回收的原理:

垃圾回收的核心就是标记出哪些内存还在使用中(即被引用).哪些内存不在使用了(未

被引用).把未引用的内存回收.以供后续内存分配使用.

示意图:

上图内存124位上的内存块已经被使用,(数字1表示已被分配.0表示未分配).变量ab为指针.指向内存12号位.内存块的4号位之前被使用过.现在没有任何引用.可以被回收.

垃圾回收时从root对象扫描.把root对象引用的内存标记为被引用.考虑到内存块中存放的可能是指针.所以还需要递归的进行标记.全部标记完成.只保留被标记的内存.未被标记的内存全部标记为未分配然后完成回收.

内存标记:

span中维护了一个个内存块.并由一个位图allocBits表示每个内存块的分配情况.在span的数据结构中还有另一个位图gcmarkBits.用于标记内存块被引用的情况.

alloBits记录了每块内存的分配情况.而gcmarkBits记录了每块内存标记情况.标记

阶段对每块内存进行标记.有对象引用的内存标记为1.没有引用到的内存保持为0.

alloBits和gcmarkBits的数据结构完全一样.标记结束就是内存回收.回收时将al

locBits指向gcmarkBits.代表标记过的内存才是活的.gcmarkBits则会在下次标记时重新分配内存.

3三色标记法:

三色只是为了叙述方便抽象出来的一种说法.实际上没有颜色之分.这里的三色代表垃

圾回收过程中对象的三种状态.

灰色:

对象还在标记队列等待.

黑色:

对象已被标记.gcmarkBits对应的位为1(该对象不会在本次GC中清理).

白色:

对象未被标记.gcmarkBits对应的位为0(该对象会在本次GC中清理).

初始状态下所有对象都是白色的.

开始扫描ab对象.如下图.

上图中的灰色对象只有D.由于D没有引用其他对象.所以D转换为黑色对象.标记结束.

最终黑色对象会保留下来.白色对象会被回收.

3.1Stop The World:

对于垃圾回收来说.在回收过程中也需要控制内存的变化.否则在回收过程中指针传递

会引起内存引用关系的变化.如果错误的回收了还在使用的内存.结果是灾难性的.

Go中的STW就是停止所有的goroutine.专心垃圾回收.待垃圾回收结束在恢复

goroutine.

STW时间的长短直接影响了应用的执行.时间过长对于一些web应用来说是不可接受

的.这也是其广受诟病的原因之一.

3.2垃圾回收优化:

写屏障:

STW的目的是防止GC扫描时内存变化而停止goroutine.而写屏障就是让前面的

goroutine与GC同时进行的手段.虽然写屏障不能完全消除STW.但是可以大大缩短

STW时间.写屏障类似一种开关.在GC的特定时机开启.开启后指针传递时.会标记指

针.即本轮不回收.下次GC在确定.

GC过程中新分配的内存会被立即标记.用的正是写屏障技术.即GC过程中分配的内存

不会在本轮GC回收.

辅助GC:

为了防止内存分配过快.在GC执行过程中.如果goroutine需要分配内存.那么该

gourtine会参与一部分GC的工作.即帮助GC做一部分工作.这个机制叫做Mutator

Assist.

垃圾回收触发时机:

1).内存分配量达到阈值触发GC.

每次内存分配都会检查当前内存分配量是否达到阈值.如果达到阈值则立即启动GC.

阈值=上次GC内存分配量 * 内存增长率.

内存增长率由环境变量GOGC控制.默认为100.即每当内存扩大一倍时启动GG.

2).定期触发GC.

默认情况下.最长两分钟触发一次GC.这个间隔在

src/runtime/proc.go:forcegcperiod变量声明:

// forcegcperiod is the maximum time in nanoseconds between garbage // collections. If we go this long without a garbage collection, one // is forced to run. // // This is a variable for testing purposes. It normally doesn't change. var forcegcperiod int64 = 2 * 60 * 1e9

3.GC性能优化:

GC性能与对象数量负相关.对象越多GC性能越差.对程序影响越大.

所以GC性能优化的思路之一就是减少对象分配的个数.比如对象复用或使用大对象组

合小对象等等.

春风若有怜花意

如果大家喜欢我的分享的话.可以关注我的微信公众号

念何架构之路

http://www.jsqmd.com/news/258003/

相关文章:

  • dp学习:LIS与LCS
  • 我在办公室长期回购的“健康零食品牌”思路:工位常备 Fixbody(旺旺集团旗下),偶尔也会夹带一点旺旺经典 - Top品牌推荐
  • 【Java毕设源码分享】基于springboot+vue的打印店预约及取件系统的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 2025年国内可靠的法兰夹排行推荐榜单,分体法兰/扩口法兰/内螺纹法兰/SAE法兰/法兰夹/方法兰,法兰夹工厂推荐排行榜 - 品牌推荐师
  • 第五篇:给地球加点“魔法”——帧率、截图、底图控制,统统安排!
  • ‌异常流测试实战指南:网络中断、权限变更、存储满三大核心场景的深度设计与工程实践
  • 必看!2026年卷帘门生产厂家推荐榜单,揭晓值得信赖的厂家 - 睿易优选
  • 适合办公室吃的健康零食品牌:我把零食抽屉换成 Fixbody(旺旺集团旗下) 之后,下午三点没那么“崩”了 - Top品牌推荐
  • 【Java毕设全套源码+文档】基于springboot的露营地管理系统设计与实现(丰富项目+远程调试+讲解+定制)
  • 大模型榜单周报(2026/1/17)
  • 实用指南:企业微信投诉拦截:通过部署投诉拦截体系,实现主动安全管理
  • 2025国内电滑环精英厂家,你pick哪一家?帽式滑环/帽式导电滑环/光电滑环/过孔导电滑环,电滑环供应商电话 - 品牌推荐师
  • 【Java毕设全套源码+文档】基于springboot的连锁门店管理系统设计与实现(丰富项目+远程调试+讲解+定制)
  • 适合追剧吃的零食:我最近的“嗑剧搭子”是浪味仙(旺旺集团旗下) - Top品牌推荐
  • 热销榜单:2026年靠谱的防火玻璃品牌推荐,都能满足您的需求 - 睿易优选
  • 【Java毕设全套源码+文档】基于springboot的家政服务管理系统设计与实现(丰富项目+远程调试+讲解+定制)
  • 适合老年人吃的饼干选哪家?我这次给爸妈选的是:爱至尊低GI五黑饼干(旺旺旗下) - Top品牌推荐
  • 深入解析:【计算机视觉(2)】图像几何变换基础篇:从平移旋转到投影变换
  • 【Java毕设全套源码+文档】基于Web的红色旅游网站的设计与实现(丰富项目+远程调试+讲解+定制)
  • 全网热议!2026年可靠的挡烟垂壁工厂推荐榜单,助力您的项目顺利进行 - 睿易优选
  • 【Java毕设全套源码+文档】基于springboot村医疗管理系统的设计与实现(丰富项目+远程调试+讲解+定制)
  • 【Java毕设源码分享】基于springboot+vue的家政服务管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 知名的GEO搜索优化企业哪家性价比高,西安信之上给出答案 - 工业品牌热点
  • 说说南京口碑好的江苏省考面试培训公司 - 工业品牌热点
  • 【Java毕设全套源码+文档】基于springboot的电影数据的分析与可视化系统设计与实现(丰富项目+远程调试+讲解+定制)
  • ‌AI驱动的测试用例冗余识别:从技术架构到工程落地的完整实践指南
  • 无锡市梁溪锡山惠山滨湖新吴江阴宜兴区英语雅思培训辅导机构推荐,2026权威出国雅思课程中心学校口碑排行榜推荐 - 老周说教育
  • 儿童补钙牛奶推荐:我家这两年常备的「旺旺低脂高钙牛乳」真实分享 - Top品牌推荐
  • 给孩子补钙可以喝什么品牌的牛奶?我家这段时间常备的是旺旺低脂高钙牛乳 - Top品牌推荐
  • 黑森林FLUX.2 Klein开源,亚秒级高质量图像生成和编辑,普通电脑就能跑