news 2026/9/3 1:42:06

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/9/2 20:15:26

【Java毕设全套源码+文档】基于springboot的打印店预约及取件系统设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/9/2 21:54:54

用javascript怎么实现网页上的文件夹上传功能?

大文件传输系统技术方案(北京教育行业国企项目) 一、系统架构设计 1.1 总体架构 渲染错误: Mermaid 渲染失败: Parse error on line 2: ... A[客户端] --> B[网关层(NginxLua)] B - -----------------------^ Expecting SQE, DOUBLECIRCLEEND, PE, …

作者头像 李华
网站建设 2026/9/3 1:24:13

破解土木求职内推难?AI技能或许是你的隐藏加速器

一份含金量高的证书不仅能在简历上加分,更能真正让你掌握撬动职场机会的杠杆。“学姐,能不能帮忙内推一下?”又到了一年求职季,当同龄人还在焦虑刷招聘网站时,部分敏锐的土木学子已经找到了新的突破口。如果说传统的求…

作者头像 李华
网站建设 2026/9/2 21:00:35

蓝易云 :linux中安装nodejs,卸载nodejs,更新nodejs,git

下面给你一套“可直接落地、可复用到运维 SOP”的方案:在 Linux 上安装 / 卸载 / 更新 Node.js,以及安装Git。默认推荐生产使用Node.js LTS(截至 2026-01,Active LTS 为 v24,Current 为 v25)。(Node.js) 1&…

作者头像 李华
网站建设 2026/9/2 21:54:00

预算有限做 PPT,我最终留下的 AI PPT 免费工具清单

预算有限做 PPT,我最终留下的 AI PPT 免费工具清单作为一个在职场摸爬滚打多年的打工人,我深知制作 PPT 的痛苦。好不容易熬夜把内容准备好了,却还得在排版、设计上花费大量时间,更别提临时被要求修改 PPT 的无奈了。而且现在市面…

作者头像 李华
网站建设 2026/9/2 21:01:24

永远要用行为去确定关系,而不是用关系去包容行为。我对你的态度是看你的行为决定的,而不是因为我们的关系好。真正的关系是建立在相互尊重、理解和正向行为基础上的,当行为出现问题时,关系不应该成为包容伤害和不

核心分析你提出的这个观点实际上触及了一个重要的心理学原理:行为主义理论。根据斯金纳的行为主义理论,人的行为是通过强化和惩罚机制形成的,而不是由关系本身决定的。关键心理学支撑:行为塑造理论:行为通过后果来学习…

作者头像 李华