JVM 的内存区域主要分为以下几个部分,每个部分都有特定的用途和管理方式。以下是 JVM 内存区域的详细划分:
1. 方法区(Method Area)
- 作用:
- 存储类的元数据信息,如类名、字段、方法信息、常量池、静态变量等。
- 特点:
- 是线程共享的内存区域。
- 在 JDK 8 之前,方法区被称为“永久代(PermGen)”;在 JDK 8 及之后,方法区由元空间(Metaspace)实现,元空间使用本地内存(Native Memory)。
- 异常:
- 如果方法区内存不足,会抛出
OutOfMemoryError
。
- 如果方法区内存不足,会抛出
2. 堆(Heap)
- 作用:
- 存储对象实例和数组。
- 是垃圾回收的主要区域。
- 特点:
- 是线程共享的内存区域。
- 堆内存分为新生代(Young Generation)和老年代(Old Generation)。
- 新生代:存放新创建的对象,分为 Eden 区、Survivor 区(From 和 To)。
- 老年代:存放长期存活的对象。
- 异常:
- 如果堆内存不足,会抛出
OutOfMemoryError
。
- 如果堆内存不足,会抛出
3. Java 栈(Java Stack)
- 作用:
- 存储方法的局部变量、操作数栈、动态链接和方法返回地址。
- 每个方法调用时会创建一个栈帧(Stack Frame),方法执行结束后栈帧被销毁。
- 特点:
- 是线程私有的内存区域。
- 栈的大小可以通过 JVM 参数
-Xss
设置。
- 异常:
- 如果栈深度超过限制(如递归调用过深),会抛出
StackOverflowError
。 - 如果栈内存不足,会抛出
OutOfMemoryError
。
- 如果栈深度超过限制(如递归调用过深),会抛出
4. 本地方法栈(Native Method Stack)
- 作用:
- 为本地方法(Native Method)服务,存储本地方法的调用信息。
- 特点:
- 是线程私有的内存区域。
- 与 Java 栈类似,但服务于本地方法。
- 异常:
- 如果栈深度超过限制或内存不足,会抛出
StackOverflowError
或OutOfMemoryError
。
- 如果栈深度超过限制或内存不足,会抛出
5. 程序计数器(Program Counter Register)
- 作用:
- 记录当前线程执行的字节码指令地址。
- 如果当前方法是本地方法,则程序计数器的值为空(Undefined)。
- 特点:
- 是线程私有的内存区域。
- 是 JVM 中唯一不会抛出
OutOfMemoryError
的区域。
6. 直接内存(Direct Memory)
- 作用:
- 直接内存并不是 JVM 运行时数据区的一部分,但它是 JVM 管理的内存。
- 主要用于 NIO(New I/O)操作,通过
ByteBuffer.allocateDirect()
分配。
- 特点:
- 直接内存的分配和回收不受 JVM 堆内存的限制,但受操作系统管理。
- 异常:
- 如果直接内存不足,会抛出
OutOfMemoryError
。
- 如果直接内存不足,会抛出
7. JVM 内存区域的总结
内存区域 | 作用 | 线程共享/私有 | 异常 |
---|---|---|---|
方法区 | 存储类的元数据、常量池、静态变量等。 | 共享 | OutOfMemoryError |
堆 | 存储对象实例和数组。 | 共享 | OutOfMemoryError |
Java 栈 | 存储方法的局部变量、操作数栈、动态链接和方法返回地址。 | 私有 | StackOverflowError / OutOfMemoryError |
本地方法栈 | 存储本地方法的调用信息。 | 私有 | StackOverflowError / OutOfMemoryError |
程序计数器 | 记录当前线程执行的字节码指令地址。 | 私有 | 无 |
直接内存 | 用于 NIO 操作,分配不受 JVM 堆内存限制。 | 共享 | OutOfMemoryError |
8. JVM 内存区域的参数设置
- 堆内存:
-Xms
:设置初始堆大小。-Xmx
:设置最大堆大小。
- 方法区(元空间):
-XX:MetaspaceSize
:设置元空间初始大小。-XX:MaxMetaspaceSize
:设置元空间最大大小。
- Java 栈:
-Xss
:设置每个线程的栈大小。
9. 总结
JVM 的内存区域主要分为:
- 方法区:存储类的元数据。
- 堆:存储对象实例和数组。
- Java 栈:存储方法的局部变量和调用信息。
- 本地方法栈:存储本地方法的调用信息。
- 程序计数器:记录当前线程执行的字节码指令地址。
- 直接内存:用于 NIO 操作。
这些内存区域共同协作,支持 Java 程序的运行,并通过垃圾回收机制自动管理内存。
THE END
暂无评论内容