news 2026/5/11 5:03:36

goroutine 栈是如何“自动扩容”的?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
goroutine 栈是如何“自动扩容”的?

前言

goroutine 初始栈很小(≈2KB),但可以自动变大。

那它是怎么做到的?


一、先说结论

goroutine 的栈扩容是通过:

在函数调用前做“栈空间检查”,如果不够,就调用 runtime 进行扩容。

关键机制是:

stack guard + morestack

二、goroutine 栈和线程栈的根本不同

线程栈

  • 创建时一次性分配(例如 1MB)
  • 固定大小
  • 不会自动扩容

goroutine 栈

  • 初始 2KB
  • 连续内存
  • 可以复制到更大的内存块
  • 原栈释放

本质是:

不够就“整体搬家”


三、栈扩容是如何触发的?

Go 在每个函数调用前都会插入一段检查代码。

类似(伪代码):

CMP SP, stackGuard JLS morestack

意思是:

当前栈指针 SP 是否快碰到 guard 线?

如果栈空间不够:

跳转到 morestack

这就是触发扩容的入口。


四、stack guard 是什么?

每个 goroutine 结构体里有:

g.stack.lo // 栈底 g.stack.hi // 栈顶 g.stackguard

stackguard是一个阈值。

当:

SP <= stackguard

说明栈快用完了。

就必须扩容。


五、morestack 做了什么?

这是扩容的核心函数。

大致流程:


① 计算需要多大栈

通常策略是:

新栈大小 = 旧栈 × 2

例如:

2KB → 4KB → 8KB → 16KB → …

指数增长。


② 分配一块更大的连续内存

在堆上分配新的栈空间。


③ 把旧栈内容复制到新栈

这是关键步骤。

因为 goroutine 栈是“连续栈”,所以:

整块内存直接 memcpy 过去。


④ 修正指针

复制后要修正:

  • 栈内的指针
  • frame pointer
  • defer 链
  • panic 结构
  • GC 元数据

因为栈地址变了。


⑤ 更新 g.stack

把 goroutine 的栈地址更新为新栈。


⑥ 继续执行原函数

扩容完成后,函数继续执行。

对程序来说是“透明的”。


六、为什么 Go 现在用“连续栈”?

早期 Go 用的是:

分段栈(segmented stack)

每次不够就链接一个新栈段。

像这样:

[segment1] -> [segment2] -> [segment3]

问题:

  • 每次函数调用都要检查段边界
  • 性能开销大
  • 复杂

后来改成:

连续栈 + 复制扩容

好处:

  • 调用更快
  • 栈布局简单
  • GC 更容易扫描

这是现代 Go 的设计。


七、栈什么时候会缩小?

扩容是自动的。

缩小也会发生,但不是立刻。

当 goroutine 进入安全点(比如 GC)时:

  • 如果发现栈用量远小于当前大小
  • runtime 可能会缩小栈

但缩小不是频繁操作。


八、一个形象类比

想象:

你租了一个 2 平米的小房间。

东西放不下了怎么办?

不是再租一个小房间接起来。

而是:

直接搬去 4 平米的房子。

再不够:

搬去 8 平米。

每次整体搬家。


九、为什么复制栈不会出问题?

因为 Go 有两个保证:

  1. 栈内指针可追踪(编译器知道哪些是指针)
  2. GC 是精确 GC(精确知道指针位置)

所以可以安全更新。


十、栈扩容和抢占的关系

有个很有意思的点:

抢占机制也复用了 stack guard。

当:

g.preempt = true

runtime 会故意把 stackguard 改成特殊值。

让下次函数调用时:

直接进入 morestack

然后在 morestack 里判断:

哦,这是抢占,不是扩容。

于是进入调度器。

这是一种“借道实现”。


十一、栈扩容的成本高吗?

扩容是:

  • 罕见操作
  • 指数增长
  • 很少发生很多次

例如:

一个 goroutine 可能一生只扩容 2~3 次。

所以总体成本可接受。


十二、终极总结

goroutine 自动扩容的机制是:

函数调用前做栈检查 → 不够则调用 morestack → 分配更大连续栈 → 复制旧栈 → 修正指针 → 继续执行

核心技术点:

  • stack guard
  • morestack
  • 连续栈复制
  • 指针修正
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 4:48:33

2026年AI智能产品开发领域十大资质审核通过的企业

2026年AI智能产品开发&#xff1a;十大专业服务商深度解析在数字化转型的浪潮中&#xff0c;企业对AI智能产品开发的需求日益增长。然而&#xff0c;如何从众多服务商中找到适合自己的合作伙伴&#xff1f;本文将通过技术实力、行业适配性和客户反馈三个维度&#xff0c;推荐十…

作者头像 李华
网站建设 2026/5/5 23:46:48

快手因低俗内容被罚1.19亿 回应称教训极其惨痛,将以此为戒

雷递网 乐天 2月7日2月6日&#xff0c;北京市互联网信息办公室依据《中华人民共和国网络安全法》《中华人民共和国行政处罚法》等法律法规&#xff0c;对北京快手科技有限公司处警告、1.191亿元罚款处罚&#xff0c;同时责令其限期改正、依法依约处置账号、从严处理责任人。事情…

作者头像 李华
网站建设 2026/5/4 15:29:36

ClickHouse 索引优化:提升大数据查询速度的秘诀

ClickHouse 索引优化&#xff1a;提升大数据查询速度的秘诀 关键词&#xff1a;ClickHouse、索引优化、大数据查询、稀疏索引、数据分区、数据排序、查询优化 摘要&#xff1a;本文深入解析ClickHouse索引体系的核心原理&#xff0c;通过稀疏索引、数据分区、排序键设计等关键技…

作者头像 李华
网站建设 2026/5/2 23:48:36

Qwen3-ASR-1.7B快速上手:音频时长限制与分段处理策略

Qwen3-ASR-1.7B快速上手&#xff1a;音频时长限制与分段处理策略 1. 引言 语音识别技术正在改变我们处理音频内容的方式。Qwen3-ASR-1.7B作为阿里通义千问推出的端到端语音识别模型&#xff0c;凭借其17亿参数和多语言支持能力&#xff0c;为开发者提供了强大的离线转写工具。…

作者头像 李华
网站建设 2026/4/21 4:20:52

AI头像生成器技术揭秘:深度学习模型架构解析

AI头像生成器技术揭秘&#xff1a;深度学习模型架构解析 1. 从一张照片到惊艳头像&#xff1a;我们到底在用什么技术 你有没有试过上传一张普通自拍照&#xff0c;几秒钟后就得到一张专业级的肖像&#xff1f;不是简单地加滤镜&#xff0c;而是连发丝纹理、皮肤质感、光影层次…

作者头像 李华
网站建设 2026/4/27 13:13:55

Shadow Sound Hunter人工智能模型核心架构解析

Shadow & Sound Hunter人工智能模型核心架构解析 1. 这个模型到底能做什么 第一次看到Shadow & Sound Hunter这个名字&#xff0c;很多人会好奇&#xff1a;这名字听起来像电影里的特工代号&#xff0c;但它其实是一个专注于多模态感知与生成的人工智能模型。简单来说…

作者头像 李华