go的GC原理以及写屏障是什么
Go语言的垃圾回收(GC)原理基于三色标记算法(Tri-color Marking Algorithm)的一个变种——三色标记-清除算法,并且引入了写屏障技术来确保并发标记阶段的正确性。
GC原理概述:
标记阶段:
- Go的垃圾回收器采用并发标记阶段,首先通过根对象(全局变量、栈上的指针等)遍历所有可达的对象,将其标记为黑色。
- 然后通过工作协程并发地追踪从黑色对象出发的所有可达对象,也将它们标记为黑色。
- 白色对象表示未被标记且不可达,即为垃圾。
标记终止阶段:
- 在并发标记结束后,需要进行STW(Stop-The-World)阶段,确保所有正在运行的协程停止,防止在标记结束阶段有新的对象引用关系变更。
清理阶段:
- 在标记完成后,垃圾回收器会清理(sweep)白色对象,释放它们占用的内存。
写屏障:
- 写屏障是Go垃圾回收器为了在并发标记阶段维护正确性而引入的一种机制。
- 写屏障在并发标记期间,每当有协程修改指针引用关系时,会拦截这些写操作,并更新相应的颜色信息,确保并发标记过程中不会漏掉任何新创建或新引用的对象。
- 在不同版本的Go GC中,写屏障的实现细节有所不同,例如早期的写屏障主要是为了处理栈上的指针,而后来引入了混合写屏障(Hybrid Write Barrier),可以处理堆上的指针,并优化了并发标记和写操作之间的交互。
写屏障的具体作用包括但不限于:
- 在并发标记期间,当一个指针从黑对象写入白对象时,写屏障会将目标对象的颜色变为灰色,并加入待标记队列,确保后续的标记阶段会正确处理这个对象。
- 在并发标记后阶段,写屏障还需要处理从任意颜色对象写入灰对象的情况,以维护并发安全。
GMP中, P的数量大小默认是多少? P的数量是固定死的还是可以手动调整的?
在Go语言的GMP(Goroutine-Worker-Mutex)调度模型中,P(Processor)的数量默认情况下并不是固定不变的,而是可以根据需要手动调整。
默认情况下,P的数量在Go程序启动时与机器的处理器核心数相等,即runtime.GOMAXPROCS()
的默认值等于系统CPU核心数。这意味着如果你不显式地更改这个值,P的数量会自动适应系统的硬件配置。
但是,你可以通过在代码中调用runtime.GOMAXPROCS(n)
函数来手动指定P的最大数量,这里的n
是你希望Go运行时能够并行执行Goroutine的最大CPU核心数或者说调度器的数量。这样做允许你根据应用程序的需求和预期负载来调整并发处理能力。
例如,如果你希望限制程序并发执行的Goroutine数量,可以设置一个比系统核心数更小的值;反之,如果希望充分利用多核优势或在特定条件下增加并发,可以设置更大的值。不过需要注意的是,过多的P并不一定能带来性能上的提升,反而可能导致上下文切换的开销增大。
最后编辑: kuteng 文档更新时间: 2024-04-02 09:53 作者:kuteng