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

为何Java 21虚拟线程内存占用比平台线程更低?

平台线程与虚拟线程的内存开销差异解析

虚拟线程切换也需要保存上下文,但方式完全不同

虚拟线程切换时确实要保存当前的执行上下文(比如程序计数器、局部变量、调用栈状态),但和平台线程的切换逻辑、内存占用不在一个量级:

  • 平台线程是内核级切换,需要完整保存/恢复内核态上下文(寄存器集合、内核栈、页表映射等),这些数据存在内核空间,每个线程都要占用额外的内核内存;
  • 虚拟线程是用户级切换(以Java为例,由JVM负责调度),仅需保存用户态的执行上下文,数据全部在用户空间,占用内存极少,且切换过程完全不涉及内核操作。

内存占用差异的核心来源

1. 栈空间的本质区别

  • 平台线程:栈是固定大小的物理内存块,通常默认分配12MB(不同语言/系统略有差异),创建时直接预留整块内存,哪怕实际只用了几KB,剩余空间也无法被其他线程复用。10000个平台线程的栈总开销就是1020GB,远超普通应用的内存上限,必然溢出。
  • 虚拟线程:栈是按需分配、可动态伸缩的虚拟栈,初始仅分配几KB空间,执行过程中需要更多栈空间时再自动扩容,闲置或栈收缩时还能释放内存给其他使用。10000个虚拟线程的初始栈总开销仅几十MB,即使运行中扩容,总内存也远低于同数量的平台线程。

2. 内核级资源的额外开销

平台线程是操作系统的原生线程,每个线程对应一个内核线程,操作系统需要为其维护大量内核级数据结构:

  • 线程控制块(TCB):存储线程ID、优先级、状态、调度信息等;
  • 内核栈:用于内核态执行时的调用栈;
  • 信号处理、锁状态等其他内核资源。

这些内核级资源的内存开销是每个平台线程都必须承担的,且系统能创建的原生线程数量受内核限制(比如Linux默认上限通常在几千到一万左右)。

而虚拟线程完全由用户态 runtime(如JVM)管理,内核看不到虚拟线程的存在,仅需维护承载虚拟线程的少量载体线程(数量通常等于CPU核心数),所有虚拟线程的调度、上下文维护都在用户态完成,不需要消耗任何内核级额外资源。

上下文维护的共性与差异

  • 两者都需要维护应用相关的执行上下文(局部变量、方法调用栈等),但存储方式不同:平台线程存在固定的物理栈,虚拟线程存在动态的虚拟栈。
  • 平台线程多了内核态上下文的维护开销,这部分是虚拟线程完全没有的,也是虚拟线程更轻量的关键因素之一。

为什么10000个虚拟线程不会内存溢出?

因为虚拟线程的总内存开销由动态伸缩的栈 + 用户态上下文数据组成,10000个实例的总内存通常在几百MB以内,远低于普通应用的内存阈值;而10000个平台线程仅栈空间就占用十几GB,再加上内核级资源开销,直接超出内存上限导致溢出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 11:42:46