jvm 内存结构
含有
- 程序计数器
- Java虚拟机栈
- 本地方法栈
- java堆
- 方法区
- 运行时常量池
- 直接内存
1. 程序计数器
每个线程有自己独有的程序计数器,用于控制程序的执行
2. Java虚拟机栈
线程私有,每个方法执行会创建自己的栈帧,用于存储
- 局部变量表
- Java虚拟机基本数据类型(boolean、byte、char、short、int、float、long、double)
- 对象引用(reference类型,它并不等同于对象本身,可能是一个指向对象起始
地址的引用指针,也可能是指向一个代表对象的句柄或者其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)。
- 操作数栈
- 动态链接
- 方法出口
3. 本地方法栈
使用native方法会使用到
4. Java堆
可以通过通过参数-Xmx和-Xms设定大小
5. 方法区
也叫永久代,用于存储
- 已被虚拟机加载的类型信息
- 常量
- 静态变量
在Java虚拟机(JVM)中,方法区(Method Area)是一个特殊的内存区域,主要用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。方法区是JVM规范的一部分,具体的实现可能因不同的JVM实现而有所不同。以下是方法区主要存储的内容:
- 类信息:这包括类的名称、直接父类的名称(除了
java.lang.Object
),它是否具有特定的属性(如public, abstract, final等),它的接口、方法、字段等。 - 运行时常量池:每个类或接口都有一个运行时常量池,用于存储编译期生成的各种字面量和符号引用,这部分内容在类和接口被加载到方法区时创建。
- 字段和方法数据:包括字段和方法的信息,如字段的名称、类型、修饰符以及方法的名称、返回类型、参数、修饰符等。
- 方法的字节码:每个方法的字节码,即实现方法的具体指令。
- 构造函数和方法的其他信息:这包括方法的本地变量表、操作数栈、捕获的异常等信息。
- 静态变量:类中定义的静态变量被存储在方法区。
- 即时编译器编译后的代码:一些JVM实现中,方法区也用于存储即时编译器编译后的代码。
需要注意的是,自Java 8起,方法区的实现有了重大变化。在Java 8中,永久代(PermGen,早期JVM中方法区的一种实现)被完全移除,取而代之的是元空间(Metaspace)。元空间不在虚拟机内存中,而是使用本地内存。这样做的主要目的是为了更好地支持动态语言,并且避免固定大小的永久代导致的内存问题。元空间主要存储类的元数据,它从本地内存中分配空间,而Java堆和方法区的其他部分仍然存在于虚拟机内存中。