在应用程序中会使用到两种内存,分别为堆(Heap)和栈(Stack),GC负责回收堆内存,而不负责回收栈中的内存。因为栈是一块专用内存,专门为了函数执行而准备的,存储着函数中的局部变量以及调用栈。除此以外,栈中的数据都有一个特点——简单。比如局部变量不能被函数外访问,所以这块内存用完就可以直接释放。正是因为这个特点,栈中的数据可以通过简单的编译器指令自动清理,并不需要通过 GC 来回收。
主流的垃圾回收算法有两大类,分别是追踪式垃圾回收算法和引用计数法( Reference counting )。而Go语言现在用的三色标记法就属于追踪式垃圾回收算法的一种,Python使用的则是后者
追踪式算法的核心思想是判断一个对象是否可达,一旦这个对象不可达就可以在垃圾回收的控制循环里被 GC 回收了。那么我们怎么判断一个对象是否可达呢?很简单,第一步找出所有的全局变量和当前函数栈里的变量,标记为可达。第二步,从已经标记的数据开始,进一步标记它们可访问的变量,以此类推。
Golang 的 GC 从 Mark-And-Sweep (标记清除)算法。到v1.5版本的基于三色标记清除的并发 垃圾收集器,大幅度降低垃圾收集的延迟从几百 ms 降低至 10ms 以下。在v1.8又使用混合写屏障 将垃圾收集的时间缩短至 0.5ms 以内。
TLDR:
strings.Join()
≈strings.Builder()
>bytes.Buffer()
>>+