<返回更多

Go语言之垃圾回收机制

2023-08-28  微信公众号  枫潇潇兮
加入收藏

什么是三色标记法

 

三色标记法是一种用于垃圾回收的算法,被广泛应用于各类编程语言的垃圾回收器中,包括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 的数量,注意内存分配的速度等,以更好地管理内存并提高程序的性能。

 

关键词:Go语言      点击(10)
声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多Go语言相关>>>