汕尾市网站建设_网站建设公司_Oracle_seo优化
2026/1/17 12:07:30 网站建设 项目流程

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

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

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

合小对象等等.

春风若有怜花意

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

念何架构之路

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询