连载中 2/20

运行时数据区:堆、栈、方法区到底怎么分

2026-09-11 · 173 阅读 · 0 评论 · 0 赞

先分清两类地皮

JVM 的内存分五块,按"归谁所有"可以一刀切成两类:线程私有的程序计数器、虚拟机栈、本地方法栈,和全局共享的堆、方法区。为什么这么分?道理很朴素——线程私有的数据(比如当前执行到哪一行)不需要同步,各用各的互不干扰;需要共享的(对象实例、类信息)才集中放在公共区域,由 GC 统一照看。

线程私有三兄弟

程序计数器是五块里最小也最安静的:记录当前线程执行到的字节码行号,是唯一不会发生 OOM 的区域。虚拟机栈才是重头戏:每个方法调用都会压入一个栈帧,里面装着局部变量表、操作数栈、动态链接和方法返回地址——方法的调用与返回,就是栈帧的入栈与出栈。

// StackOverflowError 的经典制造方式:递归没有出口
public void call() {
    call();    // 每次调用压一个栈帧,栈深 -Xss 默认 1M,很快压穿
}
// Exception in thread "main" java.lang.StackOverflowError

本地方法栈与虚拟机栈同理,区别只是服务对象:它为 native 方法(C/C++ 实现)服务。HotSpot 把两者合在了一起,日常排查时可以当作一回事。

共享的两块

堆是对象实例的主战场,也是 GC 的主战场——new 出来的东西几乎都在这里,后面所有关于垃圾回收的篇幅,追的都是这块内存。堆内部还会分新生代、老年代,那是 GC 篇的主角,这里先立个牌子。方法区存储类元信息、运行时常量池、静态变量。它的历史包袱值得一提:JDK 8 之前靠"永久代"实现,容易和堆挤在一起出各种诡异问题;JDK 8 之后改为元空间(Metaspace),搬进了本地内存,不再受堆大小约束,只受物理内存限制。

一次方法调用的完整旅程

public int calc() {
    int a = 1;                       // a 进栈帧的局部变量表
    User user = new User();          // user 引用在栈,对象本体在堆
    return a + user.getId();
}
// 调用 calc:栈帧入栈 → 执行字节码 → 结果压入操作数栈 → 栈帧出栈
// calc 结束后:栈帧整体弹出,user 引用消失
// 但 new User() 那个对象还在堆里——它生死不由栈决定,由 GC 决定

这段代码藏着一个关键认知:引用在栈上,对象在堆里。栈帧弹出只是扔掉了"地址条",真正的对象还躺在堆里等着 GC 审判——这就是后续所有内存问题排查的认知起点。

常见误区盘点

误区真相
方法区 = 永久代永久代只是 JDK 7 及以前的实现,8 之后是元空间(本地内存)
-Xmx 就是进程的全部内存堆只是大头,元空间、线程栈、直接内存都在外面,RSS 可能远超 -Xmx
栈里只放局部变量还有操作数栈、动态链接、返回地址,栈深是可调的(-Xss)
OOM 都在堆上栈、元空间、直接内存各有各的溢出方式,报错信息各不相同

地皮划分清楚了,下一篇走进堆里,跟着一行 new User() 看看对象的完整一生:怎么分配、长什么样、怎么被访问。

☕
503

10 年全栈工程师 · 503咖啡馆主理人

#运行时数据区#堆与栈#方法区#元空间#StackOverflowError

评论 (0)

热门推荐

连载中 11/22

主从搭建实操:从零配出一主两从

光讲原理不过瘾?手把手搭一主两从:my.cnf 六个参数、复制账号、GTID、CHANGE REPLICATION SOURCE TO、SHOW REPLICA STATUS 验收,附翻车排查清单。

#MySQL#主从复制#GTID#主从搭建#高可用
2026-05-07 · 10101 阅读 · 0 评论 · 0 赞
连载中 16/22

连接池:HikariCP 参数与连接风暴

连接池不是越大越好:8 核机器配 1000 连接反而更慢的数学原理,HikariCP 四个必调参数,maxLifetime 与 wait_timeout 的隐形陷阱。

#MySQL#连接池#HikariCP#maxLifetime#连接风暴
2026-05-10 · 9873 阅读 · 0 评论 · 0 赞
连载中 4/16

缓存穿透:恶意 ID 打穿 MySQL 的四道防线

请求的数据在缓存和数据库里都不存在时,缓存形同虚设。聊聊参数校验、空值缓存、布隆过滤器、限流熔断四道防线的原理与组合打法。

#Redis#缓存穿透#布隆过滤器#高可用
2026-05-16 · 9294 阅读 · 21 评论 · 287 赞