jvm 内存区域五部分:
- 程序计数器(PC)
- 虚拟机栈(JVM Stack)
- 本地方法栈(Native Method Stack)
- Java 堆内存(Java Heap)
- 方法区(Method Area)

- 程序计数器
CPU 程序计数器寄存器(x86为eip,ARM为R15),存CPU下一条指令地址,每一条指令执行时,CPU自动修改PC至下一条指令的地址
JVM 每线程有自己私有的 PC,存当前执行bytecode地址
若执行的为native方法,则PC的值为undefined
- 虚拟机栈
也是线程私有,与线程同时创建。描述了方法执行的内存模型:存局部变量表、操作数栈、动态链接、方法出口等信息
栈帧可在系统的堆上分配内存(是系统的Heap而不是Java Heap)。Java虚拟机栈所使用的内存不需要保证是连续的
- 本地方法栈
HotSpot JVM中Java虚拟机栈和本地方法栈合二为一
- 堆
供各线程共享,几乎所有对象实例和数组实例都在Java堆上分配,随JIT及逃逸分析技术发展,也可能会被优化为栈上分配)
GC收集主要区域
内存回收角度来看,分新生代和老年代,再细分可以分为Eden Space,From Survivor Space,To Survivor Space区
- 方法区
线程共享的,储存每一个类的结构信息,如运行时常量池(runtime constant pool)、字段和方法数据、构造函数和普通方法的字节码内容,还包括一些初始化的时候用到的特殊方法。方法区是堆的逻辑部分
1.7 前HotSpot JVM中,方法区位于永久代(Permanent Generation,PermGen)
永久代内可能会发生内存泄露或溢出等问题而导致的java.lang.OutOfMemoryError: PermGen ,1.7中把字符串常量,符号引用等移出了永久代
Java 8,永久代彻底地移出JVM,取而代之的是元空间(Metaspace)
- 运行时常量池
class文件中每一个类或接口的常量池表的运行时表示形式,是方法区的一部分,包括若干种不同的常量
常量池表存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放
运行时常量池具有动态性,运行期间也可以将新的量放到运行时常量池中,典型的应用是String类的intern方法:
1 |
|
1.7 字符串常量和符号引用等就被移出永久代:
- 符号引用迁移至系统堆内存(Native Heap)
- 字符串字面量迁移至Java堆(Java Heap)