Golang GC 简介

2023-10-19 17:08:45 浏览数 (2)

GC策略

垃圾回收是一种自动管理内存的技术,它负责识别和释放不再被程序引用的内存对象。在没有垃圾回收的语言中,程序员必须手动分配和释放内存,这经常导致内存泄漏和其他内存相关的错误。Go 语言的垃圾回收器自动识别和释放不再被程序引用的内存对象,使程序员能够专注于编写代码,而不必担心内存管理问题。

Go 语言的垃圾回收(Garbage Collection,简称 GC)是一种自动内存管理机制,它有助于程序员管理内存,避免了手动内存管理中的许多常见错误,如内存泄漏和悬挂指针。

Go语言的垃圾回收(GC)策略主要基于三色标记清除算法和并发执行的设计。以下是Go的GC策略的详细介绍:

1.并发执行:Go的GC在大部分时间内是并发执行的,也就是说,它在应用程序的其他部分正在运行时进行垃圾回收。这有助于减少GC对程序性能的影响。2.三色标记清除算法:Go的GC使用了一种称为"三色标记清除"的算法。这个算法将对象标记为"白色"(未访问),"灰色"(访问但未处理)和"黑色"(已处理)。GC首先将所有对象标记为白色,然后从根对象(全局变量,栈上的变量)开始,将可达的对象标记为灰色,然后逐步将灰色对象处理并标记为黑色,同时将这些对象引用的新对象标记为灰色。这个过程一直持续到所有可达对象都被标记为黑色。最后,所有仍然标记为白色的对象被视为垃圾并被回收。3.写屏障:为了在并发环境中正确地实现三色标记清除算法,Go的GC使用了一种称为"写屏障"的技术。写屏障在每次对象引用被修改时执行一些额外的操作,以确保标记过程的正确性。4.GC Pacing:Go的GC使用了一种称为"GC Pacing"的策略,以平衡内存使用和GC暂停时间。GC Pacing会根据上一次GC的统计信息来预测下一次GC的启动时间。5.最小堆占用:Go的GC会尽量保持堆的大小在一个理想的范围内,以减少内存使用。如果堆的大小超过了这个范围,GC会更频繁地运行。6.STW(Stop The World):虽然Go的GC是并发的,但在某些阶段(例如标记开始和结束阶段)仍然需要暂停程序的执行。这种情况被称为"Stop The World"。但是,Go的GC设计者已经尽力将这种暂停时间降到最低。

优缺点

Go语言的垃圾回收(GC)有许多优点,但也有一些缺点。以下是Go的GC的优缺点的介绍:

优点:

1.并发执行:Go的GC在大部分时间内是并发执行的,也就是说,它在应用程序的其他部分正在运行时进行垃圾回收。这有助于减少GC对程序性能的影响。2.简单易用:Go的GC是自动的,开发者不需要手动管理内存。这使得开发者可以更专注于程序的逻辑,而不需要担心内存泄漏等问题。3.GC Pacing:Go的GC使用了一种称为"GC Pacing"的策略,以平衡内存使用和GC暂停时间。这有助于提高程序的性能。4.最小堆占用:Go的GC会尽量保持堆的大小在一个理想的范围内,以减少内存使用。这有助于提高程序的内存效率。

缺点:

1.STW(Stop The World):虽然Go的GC是并发的,但在某些阶段(例如标记开始和结束阶段)仍然需要暂停程序的执行。这种情况被称为"Stop The World"。虽然Go的GC设计者已经尽力将这种暂停时间降到最低,但在某些情况下,这仍然可能导致程序的延迟增加。2.内存占用:虽然Go的GC会尽量保持堆的大小在一个理想的范围内,但在某些情况下,它可能会导致内存占用增加。例如,如果程序创建了大量的短暂对象,那么GC可能需要更频繁地运行,这可能会导致内存占用增加。3.GC调优有限:与一些其他语言(如Java)相比,Go的GC提供的调优选项较少。这可能会限制开发者在面对一些特殊情况时调整GC行为的能力。

如何进行配置

Go语言的垃圾回收(GC)机制在设计上是为了尽可能地自动和透明,因此,它提供的配置选项相对较少。但是,你仍然可以通过一些环境变量来调整GC的行为。以下是一些主要的配置选项:

1.GOGC:这个环境变量用于控制GC的触发频率。它的值是一个百分比,表示新分配的数据达到上一次GC后存活的数据的多少百分比时,将触发下一次GC。例如,如果GOGC=100(默认值),那么当新分配的数据达到上一次GC后存活的数据的100%时,将触发下一次GC。如果GOGC=200,那么新分配的数据需要达到存活数据的200%才会触发GC。你可以通过设置GOGC的值来平衡内存使用和GC暂停时间。2.GODEBUG:这个环境变量用于控制一些调试选项,其中一些选项可以影响GC的行为。例如,你可以设置GODEBUG=gctrace=1来打开GC追踪,这将在每次GC时打印一些详细的信息。你也可以设置GODEBUG=gcstoptheworld=1来强制GC在标记阶段使用Stop The World(STW),而不是并发执行。3.runtime/debug:这个包提供了一些函数,可以在运行时动态地控制GC。例如,你可以调用debug.SetGCPercent来动态地改变GOGC的值。你也可以调用debug.FreeOSMemory来立即触发一次GC。

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)[1]进行许可,使用时请注明出处。 Author: mengbin[2] blog: mengbin[3] Github: mengbin92[4] cnblogs: 恋水无意[5]


References

[1] 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0): https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh [2] mengbin: mengbin1992@outlook.com [3] mengbin: https://mengbin.top [4] mengbin92: https://mengbin92.github.io/ [5] 恋水无意: https://www.cnblogs.com/lianshuiwuyi/

0 人点赞