NOTE
3.8 Golang栈管理
1. 栈是什么 - 空间小,数据存放时间较短暂。栈在高地址,从高地址向低地址增长 - 分配:函数调用自动分配 - 回收:函数返回自动回收 2. Golang栈的特点 2.1. 动态扩容 - go runtime不是给每个goroutine分配固定的空间,而是需要的动态分配栈空间 - 创建gorout
这是历史学习笔记,可能存在过时或不完整的理解。
1. 栈是什么
- 空间小,数据存放时间较短暂。栈在高地址,从高地址向低地址增长
- 分配:函数调用自动分配
- 回收:函数返回自动回收
2. Golang栈的特点
2.1. 动态扩容
- go runtime不是给每个goroutine分配固定的空间,而是需要的动态分配栈空间
- 创建goroutine的时候会分配一个8KB的内存给goroutine的栈使用,用完了咋办
2026 注:8KB 是旧版本实现细节。当前 Go 的最小栈为 2KiB,实际起始栈大小还会由 runtime 调整。
- 怎么检测用完?go函数的开头有一个检测代码
- 如何扩容?参考连续栈和分段栈
2.2. 连续栈 vs 分段栈
- Go 1.3 版本前使用的栈结构是分段栈,之后使用的是连续栈
- 分段栈:
- 扩容:调用 runtime.morestack 和 runtime.newstack创建一个新的栈空间,多个栈空间会通过双向链表串起来
- 缩容:调用lessstack
- 问题:热分裂。比如循环中调用函数,又扩容又缩容
- 连续栈:
- 扩容:
- 调用runtime.newstack初始化一片比旧栈大两倍的新栈
- 调用runtime.copystack将旧栈中的所有内容复制到新的栈中
- 将指向旧栈对应变量的指针重新指向新栈
- 调用runtime.stackfree销毁并回收旧栈的内存空间
- 扩容: