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

问题描述 投票:0回答:1

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

正确答案是什么?

golang版本:go1.16.3

go stack
1个回答
5
投票

堆栈拆分与堆栈复制与其说是一种语言功能(语言规范没有提及任何一种策略),不如说它是语言的实现中的设计选择,其中有多种。因此,正如 Flimzy 在 his comment 中指出的那样,您应该指定您在问题中引用的实现。


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

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

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

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


至于gccgo(Go语言的另一种实现),Ian Lance Taylor解释说,它在这篇2010年论文(第7.4节)和这个2016年线程中使用了堆栈分割; Keith Randall 还在另一个线程中提供了有关此设计选择的一些见解。

© www.soinside.com 2019 - 2024. All rights reserved.