当前位置:  首页>> 技术小册>> GO面试指南

在 Go 中,每个 goroutine 都有一个固定大小的栈空间,用于存储局部变量、函数调用信息等。栈空间的大小默认为 2KB,但可以使用 runtime.GOMAXPROCS 函数设置。

当 goroutine 需要的栈空间超过当前大小时,会触发栈空间的扩容。扩容时,Go 会在堆空间分配一个新的栈空间,并将旧的栈空间中的数据复制到新的栈空间中,然后将当前栈指针指向新的栈空间。栈空间的大小会以指数级别增长,以减少扩容的次数。

当 goroutine 的栈空间有很多闲置空间时,会触发栈空间的缩容。缩容时,Go 会将当前栈空间中未使用的空间释放回堆空间。

下面是一个简单的示例,展示了栈空间的扩容和缩容过程:

  1. package main
  2. import (
  3. "fmt"
  4. "runtime"
  5. )
  6. func main() {
  7. var a [1024 * 1024]byte
  8. fmt.Println("stack:", &a[0], len(a))
  9. go func() {
  10. var b [4 * 1024 * 1024]byte
  11. fmt.Println("stack:", &b[0], len(b))
  12. }()
  13. for i := 0; i < 10; i++ {
  14. runtime.Gosched()
  15. }
  16. }

在该示例中,我们定义了一个大小为 1MB 的数组 a,并打印出其地址和长度。然后启动一个新的 goroutine,在其中定义一个大小为 4MB 的数组 b,并打印出其地址和长度。最后,我们使用 runtime.Gosched() 函数让当前 goroutine 让出 CPU 执行时间,给其他 goroutine 执行的机会。我们循环执行 runtime.Gosched() 函数 10 次,以保证新的 goroutine 有足够的时间执行。

运行该示例,我们可以看到输出如下:

  1. stack: 0xc000016090 1048576
  2. stack: 0xc00004a090 4194304

可以看到,数组 a 所在的栈空间大小为 1MB,数组 b 所在的栈空间大小为 4MB。这表明,在 Go 中,不同的 goroutine 可以拥有不同大小的栈空间。另外,在输出中,我们还可以看到两个数组所在的地址不同,这表明它们分别位于不同的栈空间中。


该分类下的相关小册推荐: