当前位置:首页 > 文章列表 > Golang > Go教程 > go语言垃圾回收机制是什么样的

go语言垃圾回收机制是什么样的

来源:亿速云 2023-03-09 18:15:11 0浏览 收藏

来到golang学习网的大家,相信都是编程学习爱好者,希望在这里学习Golang相关编程知识。下面本篇文章就来带大家聊聊《go语言垃圾回收机制是什么样的》,介绍一下go、go语言,希望对大家的知识积累有所帮助,助力实战开发!

今天小编给大家分享的是go语言垃圾回收机制是什么样的,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。

go语言有垃圾回收。Go语言自带垃圾回收机制(GC);GC通过独立的进程执行,它会搜索不再使用的变量,并将其释放。在计算中。内存空间包含两个重要的区域:栈区 (Stack) 和堆区 (Heap);栈区一般存储了函数调用的参数、返回值以及局部变量,不会产生内存碎片,由编译器管理,无需开发者管理;而堆区会产生内存碎片,在Go语言中堆区的对象由内存分配器分配并由垃圾收集器回收。

Go语言自带垃圾回收机制(GC)。GC 通过独立的进程执行,它会搜索不再使用的变量,并将其释放。需要注意的是,GC 在运行时会占用机器资源。

Go 语言中的垃圾回收机制 GC 详解

在计算机科学中,垃圾回收 (Garbage Collection 简称 GC) 是一种自动管理内存的机制,垃圾回收器会去尝试回收程序不再使用的对象及占用的内存

程序员受益于 GC,无需操心、也不再需要对内存进行手动的申请和释放操作,GC 在程序运行时自动释放残留的内存
GC 对程序员几乎不可见,仅在程序需要进行特殊优化时,通过提供可调控的 API,对 GC 的运行时机、运行开销进行把控的时候才得以现身

在计算中,内存空间包含两个重要的区域:栈区 (Stack) 和堆区 (Heap);栈区一般存储了函数调用的参数、返回值以及局部变量,不会产生内存碎片,由编译器管理,无需开发者管理;而堆区会产生内存碎片,在 Go 语言中堆区的对象由内存分配器分配并由垃圾收集器回收。【相关推荐:Go视频教程、编程教学】

通常,垃圾回收器的执行过程划分为两个半独立的组件:

  • 用户程序 (Mutator):用户态代码,对于 GC 而言,用户态代码仅仅只是在修改对象之间的引用关系

  • 收集器 (Colletor):负责执行垃圾回收的代码

一、内存管理和分配

当内存不再使用时,Go 内存管理由其标准库自动执行,即从内存分配到 Go 集合。内存管理一般包含三个不同的组件,分别是用户程序 (Mutator)、分配器 (Allocator) 和收集器 (Collector),当用户程序申请内存时,它会通过内存分配器申请新内存,而分配器会负责从堆中初始化相应的内存区域

go语言垃圾回收机制是什么样的

1.1 内存分配器的分配方法

在编程语言中,内存分配器一般有两种分配方法:

  • 线性分配器 (Sequential Allocator,Bump Allocator)

  • 空闲链表分配器 (Free-List Allocator)

线性分配器

线性分配 (Bump Allocator) 是一种高效的内存分配方法,但是有较大的局限性。当用户使用线性分配器时,只需要在内存中维护一个指向内存特定位置的指针,如果用户程序向分配器申请内存,分配器只需要检查剩余的空闲内存、返回分配的内存区域并修改指针在内存中的位置;

虽然线性分配器有较快的执行速度以及较低的实现复杂度,但线性分配器无法在内存释放后重用内存。如下图,如果已经分配的内存被回收,线性分配器无法重新利用红色的内存

go语言垃圾回收机制是什么样的

因此线性分配器需要与适合的垃圾回收算法配合使用

  • 标记压缩 (Mark-Compact)

  • 复制回收 (Copying GC)

  • 分代回收 (Generational GC)

以上算法可以通过拷贝的方式整理存活对象的碎片,将空闲内存定期合并,这样就能利用线性分配器的效率提升内存分配器的性能了

空闲链表分配器

空闲链表分配器 (Free-List Allocator) 可以重用已经被释放的内存,它在内部会维护一个类似链表的数据结构。当用户程序申请内存时,空闲链表分配器会依次遍历空闲的内存块,找到足够大的内存,然后申请新的资源并修改链表

go语言垃圾回收机制是什么样的

空闲链表分配器常见有四种策略:

  • 首次适应 (First-Fit) — 从链表头开始遍历,选择第一个大小大于申请内存的内存块

  • 循环首次适应 (Next-Fit) — 从上次遍历的结束位置开始遍历,选择第一个大小大于申请内存的内存块

  • 最优适应 (Best-Fit) — 从链表头遍历整个链表,选择最合适的内存块

  • 隔离适应 (Segregated-Fit) — 将内存分割成多个链表,每个链表中的内存块大小相同,申请内存时先找到满足条件的链表,再从链表中选择合适的内存块

其中第四中策略与 Go 语言中使用的内存分配策略相似

go语言垃圾回收机制是什么样的

该策略会将内存分割成由 4、8、16、32 字节的内存块组成的链表,当我们向内存分配器申请 8 字节的内存时,它会在上图中找到满足条件的空闲内存块并返回。隔离适应的分配策略减少了需要遍历的内存块数量,提高了内存分配的效率

1.2 Go 中的内存分配

一张图展示内存分配组成:

go语言垃圾回收机制是什么样的

在 Go 语言中,堆上的所有对象都会通过调用 runtime.newobject 函数分配内存,该函数会调用 runtime.mallocgc 分配指定大小的内存空间,这也是用户程序向堆上申请内存空间的必经函数

func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
	mp := acquirem()
	mp.mallocing = 1

	c := gomcache()
	var x unsafe.Pointer
	noscan := typ == nil || typ.ptrdata == 0
	if size <p>从代码中可以看出 <code>runtime.mallocgc</code> 根据对象的大小执行不同的分配逻辑,根据对象大小将它们分成微对象、小对象和大对象</p>
  • 微对象 (0, 16B) — 先使用微型分配器,再依次尝试线程缓存、中心缓存和堆分配内存

  • 小对象 [16B, 32KB] — 依次尝试使用线程缓存、中心缓存和堆分配内存

  • 大对象 (32KB, +∞) — 直接在堆上分配内存

go语言垃圾回收机制是什么样的

小分配

对于小于 32kb 的小分配,Go 会尝试从 mcache 的本地缓存中获取内存,该缓存处理一个跨度列表 (32kb 的内存块) mspan

go语言垃圾回收机制是什么样的

每个线程 M 都分配给一个处理器 P,一次最多处理一个 goroutine。在分配内存时,当前的 goroutine 将使用其当前的本地缓存 P 来查找 span 列表中第一个可用的空闲对象

大分配

Go 不使用本地缓存管理大型分配。这些大于 32kb 的分配被四舍五入到页面大小,页面直接分配到堆中

go语言垃圾回收机制是什么样的

二、垃圾回收

在 Go 语言中,垃圾回收器实现的算法是一个并发的三色标记和扫描收集器

垃回收器与 Go 程序同时运行,因此需要通过一种写屏障算法来检测内存中的潜在变化。启动写屏障的唯一条件是在短时间内停止程序,即 “Stop the World”

go语言垃圾回收机制是什么样的

写屏障的目的是允许收集器在收集期间保持堆上的数据完整性

2.1 实现原理

Go 语言的垃圾收集可以分成清除终止、标记、标记终止和清除四个不同的阶段,其中两个阶段会产生 Stop The World (STW)

go语言垃圾回收机制是什么样的

清除终止阶段

  • 暂停程序,所有的处理器在这时会进入安全点(Safe point)

  • 如果当前垃圾收集循环是强制触发的,我们还需要处理还未被清理的内存管理单元

标记阶段 (STW)

  • 将状态切换至 _GCmark、开启写屏障、用户程序协助(Mutator Assists)并将根对象入队

  • 恢复执行程序,标记进程和用于协助的用户程序会开始并发标记内存中的对象,写屏障会将被覆盖的指针和新指针都标记成灰色,而所有新创建的对象都会被直接标记成黑色

  • 开始扫描根对象,包括所有 Goroutine 的栈、全局对象以及不在堆中的运行时数据结构,扫描 Goroutine 栈期间会暂停当前处理器

  • 依次处理灰色队列中的对象,将对象标记成黑色并将它们指向的对象标记成灰色

  • 使用分布式的终止算法检查剩余的工作,发现标记阶段完成后进入标记终止阶段

标记终止阶段 (STW)

  • 暂停程序、将状态切换至 _GCmarktermination 并关闭辅助标记的用户程序

  • 清理处理器上的线程缓存

清理阶段

  • 将状态切换至 _GCoff 开始清理阶段,初始化清理状态并关闭写屏障

  • 恢复用户程序,所有新创建的对象会标记成白色

  • 后台并发清理所有的内存管理单元,当 Goroutine 申请新的内存管理单元时就会触发清理

2.2 三色标记法

三色标记算法将程序中的对象分成白色、黑色和灰色三类:

  • 白色对象 — 潜在的垃圾,其内存可能会被垃圾收集器回收

  • 黑色对象 — 活跃的对象,包括不存在任何引用外部指针的对象以及从根对象可达的对象

  • 灰色对象 — 活跃的对象,因为存在指向白色对象的外部指针,垃圾收集器会扫描这些对象的子对象

三色标记垃圾收集器的工作原理很简单,可以将其归纳成以下几个步骤:

  • 从灰色对象的集合中选择一个灰色对象并将其标记成黑色

  • 将黑色对象指向的所有对象都标记成灰色,保证该对象和被该对象引用的对象都不会被回收

  • 重复上述两个步骤直到对象图中不存在灰色对象

go语言垃圾回收机制是什么样的

关于go语言垃圾回收机制是什么样的就分享到这里了,希望以上内容可以对大家有一定的参考价值,可以学以致用。如果喜欢本篇文章,不妨把它分享出去让更多的人看到。

理论要掌握,实操不能落!以上关于《go语言垃圾回收机制是什么样的》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

版本声明
本文转载于:亿速云 如有侵犯,请联系study_golang@163.com删除
go语言能编译吗go语言能编译吗
上一篇
go语言能编译吗
go语言删除字符串字符的方法介绍
下一篇
go语言删除字符串字符的方法介绍
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 茅茅虫AIGC检测:精准识别AI生成内容,保障学术诚信
    茅茅虫AIGC检测
    茅茅虫AIGC检测,湖南茅茅虫科技有限公司倾力打造,运用NLP技术精准识别AI生成文本,提供论文、专著等学术文本的AIGC检测服务。支持多种格式,生成可视化报告,保障您的学术诚信和内容质量。
    13次使用
  • 赛林匹克平台:科技赛事聚合,赋能AI、算力、量子计算创新
    赛林匹克平台(Challympics)
    探索赛林匹克平台Challympics,一个聚焦人工智能、算力算法、量子计算等前沿技术的赛事聚合平台。连接产学研用,助力科技创新与产业升级。
    47次使用
  • SEO  笔格AIPPT:AI智能PPT制作,免费生成,高效演示
    笔格AIPPT
    SEO 笔格AIPPT是135编辑器推出的AI智能PPT制作平台,依托DeepSeek大模型,实现智能大纲生成、一键PPT生成、AI文字优化、图像生成等功能。免费试用,提升PPT制作效率,适用于商务演示、教育培训等多种场景。
    55次使用
  • 稿定PPT:在线AI演示设计,高效PPT制作工具
    稿定PPT
    告别PPT制作难题!稿定PPT提供海量模板、AI智能生成、在线协作,助您轻松制作专业演示文稿。职场办公、教育学习、企业服务全覆盖,降本增效,释放创意!
    50次使用
  • Suno苏诺中文版:AI音乐创作平台,人人都是音乐家
    Suno苏诺中文版
    探索Suno苏诺中文版,一款颠覆传统音乐创作的AI平台。无需专业技能,轻松创作个性化音乐。智能词曲生成、风格迁移、海量音效,释放您的音乐灵感!
    55次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码