知识卡片
小栈可增长
内容
Go 协程从较小栈开始,运行时在需要时扩容并迁移栈内容。它让大量协程更便宜,但也要求运行时精确掌握栈上的指针信息,和 [[深入垃圾回收全流程]] 相互关联。
参考来源
- 位置:《Go语言底层原理剖析》第9章《函数与栈》9.7节《栈扩容与栈转移原理》
- 结论依据:原文说明"在Go 1.4之后,每个栈的大小在初始化的时候都是2KB",运行时在函数序言阶段判断 SP 是否小于 stackguard0,若不够用则调用 morestack_noctxt→morestack→newstack,"新栈为旧栈的两倍大小",并将旧栈内容通过 copystack 迁移、调整所有指向旧栈的指针,因此可以推出"协程从小栈起步、由运行时按需扩容并迁移"的结论。
- 原始内容:而在Go语言中,每个协程都有一个栈,并且在Go 1.4之后,每个栈的大小在初始化的时候都是2KB……如果满足适当的条件则对栈进行扩容……函数调用链为morestack_noctxt()->morestack()->newstack(),核心代码位于newstack函数中……newstack函数首先通过栈底地址与栈顶地址相减计算旧栈的大小,并计算新栈的大小。新栈为旧栈的两倍大小……栈扩容的重要一步是将旧栈的内容转移到新栈中。