Go 的堆栈是拆分还是堆栈复制?

Hwa*_*n E 1 stack go

我对 Go 的堆栈管理感兴趣。我搜索了各种数据,但它让我感到困惑,因为所有数据都不同。我比较好奇的是,golang 的栈管理是栈拆分还是栈复制。

正确答案是什么?

golang 版本:go1.16.3

jub*_*0bs 6

堆栈拆分与堆栈复制与其说是一种语言特性——语言规范都没有提到任何一种策略——因为它是语言实现中的一种设计选择,其中有几种。因此,正如 Flimzy 在他的评论中指出的那样,您应该指定您在问题中指的是哪个实现。


Go 1.4 开始,“规范的”Go 编译器(称为gc)不再拆分堆栈,现在使用堆栈复制

堆栈现在是连续的,必要时重新分配而不是链接新的“段”;因此,此版本消除了臭名昭著的“热堆栈拆分”问题。

Brad Fitzpatrick(Go 团队的前成员)在他的 Gophercon India 2016(标记为 12'50'')中解释了 Go 编译器中堆栈拆分导致的一些问题:

[...] 在 Go 中,你有 goroutines,它就像一个非常非常轻量级的线程,它有一个很小的堆栈,并且可以根据需要增长。它过去的工作方式是使用小堆栈的小 goroutine,当你用完堆栈空间时,你会在其他地方创建另一个堆栈,当你调用函数并返回时,你会在这些堆栈之间跳转。大多数时候这很好,直到它不是,直到你处于一个紧凑的循环中,在像 JPEG 解码器之类的东西中,你在堆栈之间跳来跳去,你有非常大的性能损失,我们感到惊讶。然后你将一些代码移到其他地方,你的性能特征会发生很大变化。


至于gccgo(Go 语言的另一种实现),Ian Lance Taylor 解释说它在2016 年的线程中使用了堆栈拆分;Keith Randall 还在另一个帖子中提供了有关此设计选择的一些见解。