1.JVM内存区域划分
1.HotSpot JVM 基本架构
HotSpot JVM
主要包括3个组件:
Class Loader Subsystem
Runtime Data Areas
Execution Engine
2.程序计数器(Program Counter Register):
- 线程私有:每个线程都有自己的程序计数器。
- 存储当前线程正在执行的Java方法的
JVM
指令地址。 - 如果执行的是本地方法,则值为
undefined
。 - 唯一不会发生
OutOfMemoryError
的区域。
3.Java虚拟机栈(Java Virtual Machine Stack):
- 每个线程创建时都会创建一个虚拟机栈。
- 栈内保存一个个的栈帧(Stack Frame),对应一次次的Java方法调用。
- 栈帧中存储局部变量表、操作数栈、动态链接、方法退出定义等。
- 通过
-Xss
参数设置栈大小。 - 栈深度由方法调用链决定,递归调用可能导致栈溢出。
4.堆(Heap):
- Java内存管理的核心区域,所有线程共享。
- 用于放置Java对象实例,几乎所有创建的Java对象实例都分配在堆上。
- 是垃圾收集器重点照顾的区域,通常被进一步细分为新生代和老年代。
- 新生代(Young Generation):存放新创建的对象(Eden区、Survivor区)。
- 老年代(Old Generation):存放长期存活的对象。
- 可通过
-Xms
(初始堆大小)和-Xmx
(最大堆大小)参数配置。
5.方法区(Method Area)
- 所有线程共享的内存区域。
- 用于存储元数据,如类结构信息、运行时常量池、字段、方法代码等。
- Java 8之前:称为“永久代(PermGen)”,通过
-XX:MaxPermSize
配置。 - Java 8及之后:改为“元空间(Metaspace)”,使用本地内存,通过
-XX:MaxMetaspaceSize
限制大小。
6.运行时常量池(Run-Time Constant Pool)
- 方法区的一部分,存储编译期生成的字面量和符号引用。
- 比一般语言的符号表存储的信息更宽泛。
7.本地方法栈(Native Method Stack)
- 为
Native
方法(如C/C+&