Java虚拟机(JVM)在执行Java程序时,会将其管理的内存划分为几个不同的区域。根据Java虚拟机规范,这些区域主要包括以下几个部分:
程序计数器(Program Counter Register)
- 一块较小的内存空间,用于指示当前线程正在执行的字节码指令的位置。
- 每个线程都有自己的程序计数器。
Java虚拟机栈(Java Virtual Machine Stack)
- 线程私有的,生命周期与线程相同。
- 用于存储局部变量表、操作数栈和帧数据区等信息。
- 当方法被调用时,一个新的栈帧会被创建并压入栈顶;当方法返回时,该栈帧将被弹出并销毁。
本地方法栈(Native Method Stack)
- 类似于Java虚拟机栈,但服务于 native 方法(使用C/C++编写的代码)。
- 它为每个线程提供了一个独立的栈空间。
Java堆(Java Heap)
- 所有线程共享的一块内存区域,主要用于存放对象实例。
- 在虚拟机启动时创建,并由垃圾回收机制自动管理。
方法区(Method Area)
- 所有线程共享的内存区域,用于存储已被加载的类的信息、常量池、静态变量、即时编译后的代码等。
- 这个区域的内容是在类加载阶段被创建的,通常被称为"永久代"或"元空间"。
运行时常量池(Runtime Constant Pool)
- 是方法区的一部分,存储类文件中的符号引用、字符串常量和其他常量信息。
直接内存(Direct Memory)
- 不是Java虚拟机规范中定义的一部分,但它可以通过
java.nio
包下的Buffer类进行分配和释放。 - 直接内存不会被垃圾回收器自动回收,需要手动管理。
- 不是Java虚拟机规范中定义的一部分,但它可以通过
注意:从Java 8开始,HotSpot VM已经移除了永久代(PermGen),并将方法区替换为了元空间(Metaspace)。这使得方法区不再受制于物理内存限制,而是可以使用虚拟内存来扩展。此外,自Java 9以来,G1垃圾回收器已经成为默认的垃圾收集器,它更有效地管理了整个Java堆的内存分配和回收。