gopl-zh.github.com/ch9/ch9-08-1.md

1.6 KiB
Raw Blame History

9.8.1. 动态栈

每一个OS线程都有一个固定大小的内存块一般会是2MB来做栈这个栈会用来存储当前正在被调用或挂起指在调用其它函数时的函数的内部变量。这个固定大小的栈同时很大又很小。因为2MB的栈对于一个小小的goroutine来说是很大的内存浪费比如对于我们用到的一个只是用来WaitGroup之后关闭channel的goroutine来说。而对于go程序来说同时创建成百上千个goroutine是非常普遍的如果每一个goroutine都需要这么大的栈的话那这么多的goroutine就不太可能了。除去大小的问题之外固定大小的栈对于更复杂或者更深层次的递归函数调用来说显然是不够的。修改固定的大小可以提升空间的利用率允许创建更多的线程并且可以允许更深的递归调用不过这两者是没法同时兼备的。

相反一个goroutine会以一个很小的栈开始其生命周期一般只需要2KB。一个goroutine的栈和操作系统线程一样会保存其活跃或挂起的函数调用的本地变量但是和OS线程不太一样的是一个goroutine的栈大小并不是固定的栈的大小会根据需要动态地伸缩。而goroutine的栈的最大值有1GB比传统的固定大小的线程栈要大得多尽管一般情况下大多goroutine都不需要这么大的栈。

** 练习 9.4:** 创建一个流水线程序支持用channel连接任意数量的goroutine在跑爆内存之前可以创建多少流水线阶段一个变量通过整个流水线需要用多久这个练习题翻译不是很确定