Go 协程堆栈设计进化之旅( 三 )

< StackMin)framesize = StackMin;framesize += StackSystem;其中常量 StackExtra 是 2048 , StackMin 是 8192,StackSystem 从 0 到 512 都有可能(译者注:根据平台来判断的)
所以我们新的堆栈包括了 : 16016 (frame size) + 800 (arguments) + 2048 (StackExtra) + 0 (StackSystem)。
一旦所有的函数都调用完毕 , 新的堆栈将被释放(log runtime: oldstack ) 。 这个行为是迫使 Golang 团队转移到连续堆栈的原因之一:
当前分段堆栈机制有一个 “热分离( hot split)”的问题 —— 如果堆栈快满了 , 那么函数调用会引起一个新的堆栈块被分配 。 当所有的函>数调用返回时 , 新的堆栈块也被回收了 。 如果同样的调用方式密集地重复发生 , 分配 / 回收 将会导致大量的开销 。
因为这个问题 , Go 1.2 将最小堆栈大小增长到了 8Kb 。 之后因为实现了连续堆栈 , 则将堆栈大小缩减回了 2Kb 。
下图是分段堆栈的演示图:
Go 协程堆栈设计进化之旅文章插图
Golang stack growth with segmented stack
总结Go 的堆栈管理是非常高效的 , 而且容易理解 。 Golang 不是唯一一个没有选择分段堆栈的语言 ,Rust 语言因为同样的原因而没有选择这个方案 。
如果你想了解更深入的堆栈内容 , 可以阅读 Dave Cheney 的博客文章 , 该文章讨论了 redzone, 还有 Bill Kennedy 的文章解释了堆栈中的 frames 。
阅读原文: