JMM内存划分本质是逻辑抽象:堆和方法区为线程共享,虚拟机栈、本地方法栈、程序计数器为线程私有;边界由生命周期与数据归属决定,非物理地址分隔。

线程私有区域和线程共享区域的“边界”不是物理内存地址上的硬性分隔,而是由JVM规范定义的逻辑职责与生命周期决定的——关键看数据归属谁、何时分配、是否需同步保护。
线程私有区域:每个线程独占一份,互不干扰
这类区域随线程创建而分配,随线程结束而回收,天然隔离,无需加锁。具体包括:
- 程序计数器:记录当前线程正在执行的字节码指令地址,仅存行号信息,内存极小,不会OOM
- Java虚拟机栈:存储方法调用的栈帧,含局部变量表、操作数栈等;每个方法调用对应一个栈帧,深度超限抛StackOverflowError,空间不足抛OutOfMemoryError
- 本地方法栈:为Native方法服务,功能类似虚拟机栈,HotSpot中常与虚拟机栈合二为一
线程共享区域:所有线程共用同一份,需并发控制
这些区域在JVM启动时初始化,关闭时释放,是GC重点管理区,也是线程安全问题集中地:
- Java堆(Heap):存放new出来的对象实例和数组,划分为新生代(Eden、Survivor)、老年代;所有线程通过引用访问堆中对象,修改共享对象状态必须考虑同步
- 方法区(Method Area):JDK 8+ 实际实现为元空间(Metaspace),存储类信息、常量、静态变量、即时编译代码;类型加载后在此注册,被所有线程共享
- 运行时常量池:属于方法区的一部分,存放编译期生成的字面量和符号引用,如字符串常量、final静态字段值
特别注意:直接内存不属于JVM运行时数据区
它由操作系统直接分配,通过java.nio.DirectByteBuffer操作,虽常被误认为“堆外内存”,但既不归JVM自动管理,也不受GC控制。它的使用不受堆大小参数(-Xmx)限制,但受限于系统总内存,滥用会导致直接的OutOfMemoryError: Direct buffer memory。
立即学习“Java免费学习笔记(深入)”;
边界判断的核心依据
不用记地址范围,只需抓住三个判断维度:
- 生命周期是否绑定线程 → 是则私有
- 同一块数据是否会被多个线程同时读写 → 是则共享
- 是否参与垃圾回收 → 堆和方法区是GC主战场,私有区不参与


















