news 2026/4/26 15:41:56

Go进阶之垃圾回收

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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性能优化的思路之一就是减少对象分配的个数.比如对象复用或使用大对象组

合小对象等等.

春风若有怜花意

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

念何架构之路

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/26 15:41:10

‌用AI做国际化测试:自动生成多语言环境下的文本溢出测试

一、背景与挑战:为什么文本溢出是国际化测试的“隐形杀手”‌国际化(i18n)测试的核心目标,是确保软件在不同语言、文化与区域设置下保持功能完整与视觉一致。然而,‌文本溢出(Text Overflow)‌—…

作者头像 李华
网站建设 2026/4/17 18:48:58

为什么AI生成的测试用例总能发现“逻辑漏洞“?

一、传统测试的认知茧房与AI的破壁利器在软件测试领域,逻辑漏洞如同潜伏在代码深处的幽灵。传统测试方法依赖测试工程师的经验积累与需求文档推导,这种基于确定性的测试设计存在三重天然局限:路径依赖陷阱人类测试者容易陷入"需求文档即…

作者头像 李华
网站建设 2026/4/26 15:39:37

ssm626智能办公系统请假销假薪酬工资vue主管

目录SSM626智能办公系统功能摘要开发技术源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!SSM626智能办公系统功能摘要 请假销假模块 采用Vue.js前端框架实现动态表单交互,员工可在线提交请假类型(事假、病假、年…

作者头像 李华
网站建设 2026/4/26 15:39:42

ssm637网络购物商城系统vue

目录系统概述技术架构核心功能创新点应用价值开发技术源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!系统概述 SSM637网络购物商城系统基于Vue.js前端框架与SSM(SpringSpring MVCMyBatis)后端架构开发&#xff…

作者头像 李华
网站建设 2026/4/26 13:30:17

电脑无法加载驱动怎么解决?教你手动安装正确方法

设备驱动程序是硬件与操作系统沟通的桥梁,当它无法加载时,相关设备将无法正常工作。这个问题通常由驱动文件损坏、系统兼容性或权限冲突引起,并非无法解决。理解其根源并掌握正确的排查方法,是快速修复的关键。 为什么电脑无法加载…

作者头像 李华
网站建设 2026/4/23 4:01:15

AI辅助绘图实战:从文字到流程图一步到位,全套实操步骤详解

用AI生成流程图,能帮你把原本1小时的绘制工作压缩到10分钟内完成。不管是学生梳理学习路径、职场新人撰写工作方案,还是小老板规范业务流程,都能大幅提升效率。 但很多人卡在“不会设计”“工具太复杂”上,其实选对AI工具就能轻松…

作者头像 李华