You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么协程占用内存比线程更少?有栈协程为何仍更省内存?

协程被称为“轻量级线程”:内存占用更低的核心原因

很多人疑惑,既然有栈协程也有独立栈,为啥内存占用比线程低?核心在于线程(尤其是内核线程)包含大量协程不需要的内核态和用户态开销:

一、内核态的额外存储开销

线程是操作系统直接管理的内核对象,每个线程都要占用内核空间的额外资源:

  • 内核栈:每个线程都有独立的内核栈(通常几KB到几十KB),用于处理系统调用、中断时保存内核态的寄存器上下文。协程是用户态调度的,完全不需要内核栈,所有上下文都在用户进程空间内。
  • 线程控制块(TCB):操作系统需要维护每个线程的TCB,里面包含优先级、调度状态(就绪/阻塞/运行)、信号掩码、进程资源引用(比如文件描述符表、内存映射表的关联信息)、调度队列指针等大量元数据。这些元数据都存在内核空间,占用的内存远大于协程在用户态维护的简单调度信息(比如仅保存程序计数器、栈指针、少量寄存器)。

二、用户态的内存利用率差异

即使只看用户态的栈,线程和有栈协程也有明显区别:

  • 栈的大小与分配方式:线程的用户栈通常是固定的大尺寸(比如Linux默认8MB),并且提前占用虚拟内存空间(物理内存按需分配,但虚拟地址会被预留)。而有栈协程的栈初始尺寸极小(比如Go的goroutine初始栈仅2KB),还能动态扩容/缩容,内存利用率远高于线程。
  • 线程局部存储(TLS):每个线程都有独立的TLS区域,用于存储线程局部变量,操作系统需要维护TLS的映射和管理结构。协程的局部变量直接存在自己的栈中,不需要额外的TLS开销(除非语言实现刻意添加,但并非必需)。

三、调度切换的间接内存开销

线程切换需要陷入内核态,除了保存/恢复大量寄存器,还要刷新TLB(翻译后备缓冲器),这会导致内核栈的临时内存占用增加,同时触发更多的内存页交换。而协程切换完全在用户态完成,只需要保存少量关键寄存器(程序计数器、栈指针等),几乎没有额外的内存开销。

内容的提问来源于stack exchange,提问作者DiplomateProgrammer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 19:02:41