3.4 Go 的默认栈大小是多少?最大值多少?

Go 语言使用用户态线程 Goroutine 作为执行上下文,它的额外开销和默认栈大小都比线程小很多,然而 Goroutine 的栈内存空间和栈结构也在早期几个版本中发生过一些变化:

  • v1.0 ~ v1.1 — 最小栈内存空间为 4KB;

  • v1.2 — 将最小栈内存提升到了 8KB;

  • v1.3 — 使用连续栈替换之前版本的分段栈;

  • v1.4 — 将最小栈内存降低到了 2KB;

Goroutine 的初始栈内存在最初的几个版本中多次修改,从 4KB 提升到 8KB 是临时的解决方案,其目的是为了减轻分段栈的栈热分裂问题对程序造成的性能影响;

在 v1.3 版本引入连续栈之后,Goroutine 的初始栈大小降低到了 2KB,进一步减少了 Goroutine 占用的内存空间。

这个栈比 x86_64 构架下线程的默认栈 2M 要小很多,真的是轻量级的用户态线程。

关于这个初始值和最大值嘛,在 Go 的源码 runtime/stack.go 里其实都可以找到

// rumtime.stack.go
// The minimum size of stack used by Go code
_StackMin = 2048

var maxstacksize uintptr = 1 << 20 // enough until runtime.main sets it for real

那么这个 1<<20 代表多大呢?使用 Python 计算一下是 1G

>>> 1<<20
1048576
>>> 1048576/1024/1024
1.0