jvm内存结构分为线程私有(程序计数器、虚拟机栈、本地方法栈)和线程共享(堆、方法区)两大区域;私有区域随线程生灭,共享区域由gc管理,对象实例存堆,类信息存方法区,引用变量存栈,字面量存常量池。

线程私有区域:每个线程自带的“小背包”
就像每个程序员写代码时都有自己的编辑器窗口和本地变量,JVM 为每个线程分配独立的内存空间,互不干扰。
- 程序计数器:记录当前线程正在执行到哪一行字节码。它是唯一不会发生内存溢出(OOM)的区域,本质是 CPU 寄存器的映射。
-
虚拟机栈:方法调用的“执行现场”。每次调用一个 Java 方法,就压入一个栈帧;方法结束,栈帧弹出。栈帧里装着局部变量、方法参数、计算用的操作数栈等。递归太深会报
StackOverflowError。 -
本地方法栈:功能类似虚拟机栈,但服务对象是用 C/C++ 写的 native 方法(比如
System.gc())。HotSpot 虚拟机通常把它和虚拟机栈合在一起。
线程共享区域:大家共用的“公共仓库”
所有线程都能读写这些区域,也是 JVM 垃圾回收(GC)重点盯防的地方。
-
堆(Heap):最大的一块内存,几乎所有的对象实例都诞生在这里。它被逻辑划分为新生代(放新创建、存活短的对象)和老年代(放长期存活的对象)。堆大小可通过
-Xms和-Xmx参数控制。 -
方法区(Method Area):存储类的结构信息——比如类名、字段、方法字节码、常量池、静态变量等。JDK 8+ 中由“元空间(Metaspace)”实现,使用的是本地内存(即操作系统的物理内存),不再属于堆,因此不容易因类太多而抛出
OutOfMemoryError: PermGen space。
记住两个核心区分逻辑
初学阶段抓住这两条线,就能快速定位问题:
- 私有 vs 共享:程序计数器、虚拟机栈、本地方法栈随线程生灭;堆和方法区由整个 JVM 进程管理,所有线程共用。
- 谁负责回收:GC 主要清理堆中的无用对象;方法区里的类卸载、常量池回收也受 GC 影响;而三个私有区域随着线程结束自动释放,不需要 GC 干预。
一个小例子帮你串起来
写一句 String s = new String("hello");:
-
s这个引用变量存在当前线程的虚拟机栈中; -
"hello"字符串字面量存在方法区的运行时常量池; -
new String(...)创建的实际对象存在堆中; - 当前线程执行到这一行的字节码位置,由程序计数器记录。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











