搜索
首页后端开发Golanggo语言有垃圾回收吗

go语言有垃圾回收吗

Dec 09, 2022 pm 07:42 PM
gogolanggo语言垃圾回收

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

go语言有垃圾回收吗

本教程操作环境:windows7系统、GO 1.18版本、Dell G3电脑。

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),当用户程序申请内存时,它会通过内存分配器申请新内存,而分配器会负责从堆中初始化相应的内存区域

1.png

1.1 内存分配器的分配方法

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

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

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

线性分配器

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

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

2.png

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

  • 标记压缩 (Mark-Compact)

  • 复制回收 (Copying GC)

  • 分代回收 (Generational GC)

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

空闲链表分配器

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

3.png

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

  • 首次适应 (First-Fit) — 从链表头开始遍历,选择第一个大小大于申请内存的内存块
  • 循环首次适应 (Next-Fit) — 从上次遍历的结束位置开始遍历,选择第一个大小大于申请内存的内存块
  • 最优适应 (Best-Fit) — 从链表头遍历整个链表,选择最合适的内存块
  • 隔离适应 (Segregated-Fit) — 将内存分割成多个链表,每个链表中的内存块大小相同,申请内存时先找到满足条件的链表,再从链表中选择合适的内存块

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

4.png

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

1.2 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 <= maxSmallSize {
		if noscan && size < maxTinySize {
			// 微对象分配
		} else {
			// 小对象分配
		}
	} else {
		// 大对象分配
	}

	publicationBarrier()
	mp.mallocing = 0
	releasem(mp)

	return x}

从代码中可以看出 runtime.mallocgc 根据对象的大小执行不同的分配逻辑,根据对象大小将它们分成微对象、小对象和大对象

  • 微对象 (0, 16B) — 先使用微型分配器,再依次尝试线程缓存、中心缓存和堆分配内存
  • 小对象 [16B, 32KB] — 依次尝试使用线程缓存、中心缓存和堆分配内存
  • 大对象 (32KB, +∞) — 直接在堆上分配内存

6.png

小分配

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

7.png

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

大分配

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

8.png

二、垃圾回收

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

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

9.png

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

2.1 实现原理

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

10.png

清除终止阶段

  • 暂停程序,所有的处理器在这时会进入安全点(Safe point)
  • 如果当前垃圾收集循环是强制触发的,我们还需要处理还未被清理的内存管理单元

标记阶段 (STW)

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

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

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

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

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

标记终止阶段 (STW)

  • 暂停程序、将状态切换至 _GCmarktermination 并关闭辅助标记的用户程序
  • 清理处理器上的线程缓存

清理阶段

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

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

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

2.2 三色标记法

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

  • 白色对象 — 潜在的垃圾,其内存可能会被垃圾收集器回收
  • 黑色对象 — 活跃的对象,包括不存在任何引用外部指针的对象以及从根对象可达的对象
  • 灰色对象 — 活跃的对象,因为存在指向白色对象的外部指针,垃圾收集器会扫描这些对象的子对象

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

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

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

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

11.png

更多编程相关知识,请访问:编程视频!!

以上是go语言有垃圾回收吗的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
Golang vs.C:代码示例和绩效分析Golang vs.C:代码示例和绩效分析Apr 15, 2025 am 12:03 AM

Golang适合快速开发和并发编程,而C 更适合需要极致性能和底层控制的项目。1)Golang的并发模型通过goroutine和channel简化并发编程。2)C 的模板编程提供泛型代码和性能优化。3)Golang的垃圾回收方便但可能影响性能,C 的内存管理复杂但控制精细。

Golang的影响:速度,效率和简单性Golang的影响:速度,效率和简单性Apr 14, 2025 am 12:11 AM

GoimpactsdevelopmentPositationalityThroughSpeed,效率和模拟性。1)速度:gocompilesquicklyandrunseff,ifealforlargeprojects.2)效率:效率:ITScomprehenSevestAndArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdEcceSteral Depentencies,增强开发的简单性:3)SimpleflovelmentIcties:3)简单性。

C和Golang:表演至关重要时C和Golang:表演至关重要时Apr 13, 2025 am 12:11 AM

C 更适合需要直接控制硬件资源和高性能优化的场景,而Golang更适合需要快速开发和高并发处理的场景。1.C 的优势在于其接近硬件的特性和高度的优化能力,适合游戏开发等高性能需求。2.Golang的优势在于其简洁的语法和天然的并发支持,适合高并发服务开发。

Golang行动:现实世界中的示例和应用程序Golang行动:现实世界中的示例和应用程序Apr 12, 2025 am 12:11 AM

Golang在实际应用中表现出色,以简洁、高效和并发性着称。 1)通过Goroutines和Channels实现并发编程,2)利用接口和多态编写灵活代码,3)使用net/http包简化网络编程,4)构建高效并发爬虫,5)通过工具和最佳实践进行调试和优化。

Golang:Go编程语言解释了Golang:Go编程语言解释了Apr 10, 2025 am 11:18 AM

Go语言的核心特性包括垃圾回收、静态链接和并发支持。1.Go语言的并发模型通过goroutine和channel实现高效并发编程。2.接口和多态性通过实现接口方法,使得不同类型可以统一处理。3.基本用法展示了函数定义和调用的高效性。4.高级用法中,切片提供了动态调整大小的强大功能。5.常见错误如竞态条件可以通过gotest-race检测并解决。6.性能优化通过sync.Pool重用对象,减少垃圾回收压力。

Golang的目的:建立高效且可扩展的系统Golang的目的:建立高效且可扩展的系统Apr 09, 2025 pm 05:17 PM

Go语言在构建高效且可扩展的系统中表现出色,其优势包括:1.高性能:编译成机器码,运行速度快;2.并发编程:通过goroutines和channels简化多任务处理;3.简洁性:语法简洁,降低学习和维护成本;4.跨平台:支持跨平台编译,方便部署。

SQL排序中ORDER BY语句结果为何有时看似随机?SQL排序中ORDER BY语句结果为何有时看似随机?Apr 02, 2025 pm 05:24 PM

关于SQL查询结果排序的疑惑学习SQL的过程中,常常会遇到一些令人困惑的问题。最近,笔者在阅读《MICK-SQL基础�...

技术栈收敛是否仅仅是技术栈选型的过程?技术栈收敛是否仅仅是技术栈选型的过程?Apr 02, 2025 pm 05:21 PM

技术栈收敛与技术选型的关系在软件开发中,技术栈的选择和管理是一个非常关键的问题。最近,有读者提出了...

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
1 个月前By尊渡假赌尊渡假赌尊渡假赌

热工具

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具