您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > Go语言

Go语言之垃圾回收机制

时间:2023-08-28 15:38:33  来源:微信公众号  作者:枫潇潇兮

什么是三色标记法

 

三色标记法是一种用于垃圾回收的算法,被广泛应用于各类编程语言的垃圾回收器中,包括Go语言

这种算法将对象划分成三种颜色:

  1. 白色:表示对象是垃圾,可以被释放。也就是说,这是那些从根(root)节点开始无法触及的对象。

  2. 黑色:表示对象是存活的,并且这个对象引用的所有对象也已被访问和标记。

  3. 灰色:表示对象是存活的,但是这个对象引用的其他对象还没有被访问和标记。

算法开始时,所有对象都标记为白色,然后从根节点开始遍历,遍历到的对象标记为灰色。接着选择一个灰色对象,把它引用的所有白色对象都标记为灰色,然后把自己标记为黑色。这个过程一直进行,直到没有灰色对象。此时,所有存活的对象都被标记为黑色,而所有死亡(不可达或无用)的对象都仍然是白色,GC会回收这些白色对象。

整个过程中的重点在于,如果所有的灰色对象指向的对象都已经处理(标记为黑色),则说明所有的可达对象都已访问(标记为黑色),非黑即白,那么所有的白色对象为不可达对象,可被清理。

 

Go垃圾回收机制

Go语言的垃圾回收(Garbage Collection,简称GC)机制是自动回收系统中不再使用的内存的功能。这对于开发者来说非常方便,因为它省去了手动管理内存的需求。

垃圾回收机制在Go语言中的执行过程主要由以下几个步骤组成:

  1. 标记清除:首先,垃圾回收器会标记出所有生存对象,然后清除所有没有被标记的对象。

  2. 并发标记:在这个阶段,垃圾回收器会在用户goroutine后台进行,并试图在标记阶段结束之前标记所有的生存对象。

  3. 标记终止:在这个阶段,所有的用户goroutine都会停止,垃圾回收器会进行最后的检查并清除所有未标记的对象。

  4. 扫描:在清除了所有未标记的对象之后,垃圾回收器将进行内存清扫,归还未使用的内存给操作系统。

其中,“并发标记清除”是Go的垃圾回收器的一大特点,它大部分时间与用户的goroutine并发执行,只有在GC的开始和结束阶段才会暂停goroutine。

Go的GC还支持开发者通过runtime的方法来进行设置和调整,比如设置GC百分比、手动触发GC等,以满足更精细化的内存管理需求。

 

 

Stop The World

    Go语言在执行垃圾回收时,会有两次STW(Stop The World,简称停工)事件。

第一次停工事件发生在垃圾回收的"并发标记"阶段开始之前,这次停工是为了确保所有的goroutine都写回自己的栈信息,使垃圾回收器能够正确地找到所有根对象。这次停工的时间通常非常短,因为对栈进行扫描的操作一般很快就能完成。

第二次停工事件发生在"并发标记"阶段结束后,垃圾回收进入到"标记终止"阶段。这次停工主要是为了处理在"并发标记"阶段可能遗漏掉的对象。这个阶段包括处理分配在"并发标记"阶段的对象,处理在"并发标记"阶段产生的写屏障,以及对heap进行最后一次扫描。这次停工的时间与heap的大小、写屏障的数量以及"并发标记"阶段分配的对象数量有关,通常也会尽力控制在可以接受的范围之内。

总的来说,Go语言尽量减少了垃圾回收中的停工时间,同时通过并发进行垃圾回收,使得Go语言的垃圾回收相较于其他一些语言的垃圾回收,对程序执行的影响更小。

 

以下情况可能会影响Go语言的STW (Stop The World) 的时间:

  1. 大量的内存使用:如果程序使用了大量内存,垃圾回收器需要扫描更多的对象,这就可能增加STW的时长。

  2. 大量的 Goroutine:每个 Goroutine 都会增加STW的时间,因为在两次STW期间,它们的调度状态和栈必须被扫描。

  3. 写屏障的开启状态:在并发标记阶段,一旦对象被灰度标记,如果应用程序试图更改该对象,必须先开启写屏障来标记任何新分配或者即将被覆盖的对象。因此,过多的写操作会增加STW的时间。

  4. 分配速度:在垃圾回收过程中,如果内存分配的速度快于垃圾回收的速度,可能会导致内存空间不断增长,从而延长STW的时间。

这些情形都可能导致STW时间的增加,因此在编写代码时,开发者需要尽量减少内存的使用,控制 Goroutine 的数量,注意内存分配的速度等,以更好地管理内存并提高程序的性能。

 



Tags:Go语言   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
宝藏级Go语言开源项目——教你自己动手开发互联网搜索引擎
DIYSearchEngine 是一个能够高速采集海量互联网数据的开源搜索引擎,采用 Go 语言开发。Github 地址:https://github.com/johnlui/DIYSearchEngine运行方法首先,给自己准备一杯...【详细内容】
2024-03-12  Search: Go语言  点击:(18)  评论:(0)  加入收藏
你是否想知道如何应对高并发?Go语言为你提供了答案!
并发编程是当前软件领域中不可忽视的一个关键概念。随着CPU等硬件的不断发展,我们都渴望让我们的程序运行速度更快、更快。而Go语言在语言层面天生支持并发,充分利用现代CPU的...【详细内容】
2023-12-29  Search: Go语言  点击:(107)  评论:(0)  加入收藏
Go语言实现GoF设计模式:适配器模式
简介适配器模式(Adapter)是最常用的结构型模式之一,在现实生活中,适配器模式也是处处可见,比如电源插头转换器,它可以让英式的插头工作在中式的插座上。GoF 对它的定义如下:Convert...【详细内容】
2023-12-12  Search: Go语言  点击:(207)  评论:(0)  加入收藏
Go语言字符串拼接方式与性能比较,分析过没?
在Go语言中,字符串拼接性能是相当高效的,主要原因有两点:一是字符串在Go中是不可变的(immutable),二是Go语言提供了strings.Builder类型来高效处理字符串拼接。1. 字符串是不可变...【详细内容】
2023-12-11  Search: Go语言  点击:(229)  评论:(0)  加入收藏
一篇学会AI与Go语言无缝对接
在当今应用开发领域,类似OpenAI API等生成式AI技术的蓬勃发展正在彻底改变着应用开发的格局。Python和JavaScript等语言已经拥有丰富的资源来支持这些技术,其中LangChain就是...【详细内容】
2023-12-04  Search: Go语言  点击:(141)  评论:(0)  加入收藏
20小时快速入门Go语言
Go语言是由Google开发的一种高效、简洁和并发性强的编程语言,其设计目标是使得程序员能够更加容易地创建可靠、高效的软件。尽管Go语言的语法相对其他编程语言来说可能更加陌...【详细内容】
2023-12-03  Search: Go语言  点击:(154)  评论:(0)  加入收藏
十个令人惊叹的Go语言技巧,让你的代码更加优雅
在开发生产项目的过程中,我注意到经常会发现自己在重复编写代码,使用某些技巧时没有意识到,直到后来回顾工作时才意识到。为了解决这个问题,我开发了一种解决方案,对我来说非常有...【详细内容】
2023-11-20  Search: Go语言  点击:(172)  评论:(0)  加入收藏
Go语言Context应用全攻略:异步编程利器
概述在 Go 语言中,Context(上下文)是一个非常重要的概念,特别是在处理请求时。允许在请求的整个生命周期内传递数据、控制请求的取消、处理超时等。本文将介绍 Go 语言中 Contex...【详细内容】
2023-11-06  Search: Go语言  点击:(304)  评论:(0)  加入收藏
Go语言高级特性:Context深入解读
概述在 Go 语言中,context(上下文)是一个非常重要的概念。它主要用于在多个 goroutine 之间传递请求特定任务的截止日期、取消信号以及其他请求范围的值。3. Context 的取消与...【详细内容】
2023-11-01  Search: Go语言  点击:(232)  评论:(0)  加入收藏
Go语言中如何实现JWT
什么JWTJWT(JSON Web Token)是一种开放标准(RFC 7519),定义了一种在各方之间安全传输信息的简洁方式。这些信息可以被验证和信任,因为它们是数字签名的。JWT由三部分组成,用.分隔。...【详细内容】
2023-09-11  Search: Go语言  点击:(250)  评论:(0)  加入收藏
▌简易百科推荐
宝藏级Go语言开源项目——教你自己动手开发互联网搜索引擎
DIYSearchEngine 是一个能够高速采集海量互联网数据的开源搜索引擎,采用 Go 语言开发。Github 地址:https://github.com/johnlui/DIYSearchEngine运行方法首先,给自己准备一杯...【详细内容】
2024-03-12  OSC开源社区    Tags:Go语言   点击:(18)  评论:(0)  加入收藏
Go Gin框架实现优雅地重启和停止
在Web应用程序中,有时候我们需要重启或停止服务器,无论是因为更新代码还是进行例行维护。在这种情景下,我们需要保证应用程序的可用性和数据的一致性。这就需要优雅地关闭和重...【详细内容】
2024-01-30  源自开发者  微信公众号  Tags:Go   点击:(67)  评论:(0)  加入收藏
如何让Go程序以后台进程或daemon方式运行
本文探讨了如何通过Go代码实现在后台运行的程序。最近我用Go语言开发了一个WebSocket服务,我希望它能在后台运行,并在异常退出时自动重新启动。我的整体思路是将程序转为后台...【详细内容】
2024-01-26  Go语言圈  微信公众号  Tags:Go程序   点击:(60)  评论:(0)  加入收藏
深入Go底层原理,重写Redis中间件实战
Go语言以其简洁、高效和并发性能而闻名,深入了解其底层原理可以帮助我们更好地利用其优势。在本文中,我们将探讨如何深入Go底层原理,以及如何利用这些知识重新实现一个简单的Re...【详细内容】
2024-01-25  547蓝色星球    Tags:Go   点击:(66)  评论:(0)  加入收藏
Go 内存优化与垃圾收集
Go提供了自动化的内存管理机制,但在某些情况下需要更精细的微调从而避免发生OOM错误。本文将讨论Go的垃圾收集器、应用程序内存优化以及如何防止OOM(Out-Of-Memory)错误。Go...【详细内容】
2024-01-15  DeepNoMind  微信公众号  Tags:Go   点击:(61)  评论:(0)  加入收藏
Go函数指针是如何让你的程序变慢的?
导读Go 语言的常规优化手段无需赘述,相信大家也能找到大量的经典教程。但基于 Go 的函数值问题,业界还没有太多深度讨论的内容分享。本文作者根据自己对 Go 代码的使用与调优...【详细内容】
2024-01-15  腾讯云开发者  微信公众号  Tags:Go函数   点击:(86)  评论:(0)  加入收藏
Go编程中调用外部命令的几种场景
在很多场合, 使用Go语言需要调用外部命令来完成一些特定的任务, 例如: 使用Go语言调用Linux命令来获取执行的结果,又或者调用第三方程序执行来完成额外的任务。在go的标准库...【详细内容】
2024-01-09  suntiger    Tags:Go编程   点击:(102)  评论:(0)  加入收藏
Go 语言不支持并发读写 Map,为什么?
Go语言的map类型不支持并发读写的主要原因是并发读写会导致数据竞态(data race),这意味着多个 goroutine 可能同时访问并修改同一个 map,从而引发不确定的结果。在Go语言的设计...【详细内容】
2024-01-05  Go语言圈  微信公众号  Tags:Go 语言   点击:(77)  评论:(0)  加入收藏
Go微服务入门到容器化实践
Go微服务入门到容器化实践Go 是一门高效、现代化、快速增长的编程语言,非常适合构建 Web 应用程序。而 Docker 是一种轻量级的容器化技术,能够使得您的应用程序在任何地方运行...【详细内容】
2024-01-01  大雷家吃饭    Tags:Go微服务   点击:(62)  评论:(0)  加入收藏
你是否想知道如何应对高并发?Go语言为你提供了答案!
并发编程是当前软件领域中不可忽视的一个关键概念。随着CPU等硬件的不断发展,我们都渴望让我们的程序运行速度更快、更快。而Go语言在语言层面天生支持并发,充分利用现代CPU的...【详细内容】
2023-12-29  灵墨AI探索室  微信公众号  Tags:Go语言   点击:(107)  评论:(0)  加入收藏
站内最新
站内热门
站内头条