JVM内存划分
1.Java文件如何被JVM加载到内存中?
那么这些内存区域到底是干什么呢?往下看
2.内存区域划分
2.1 程序计数器
虚拟机中一块较小的内存空间,主要用于记录当前线程执行的位置。
那么为什么需要记录当前线程执行的位置呢?
因为 Java是多线程的,CPU在多线程中分配执行时间片段。当一线程被CPU挂起时,就需要记录已经执行到的位置,再次执行时,就可以从哪行指令开始执行。
思考一下程序计数器为什么是线程私有的,上面同样可以给到你启发。
2.2 虚拟机栈
同样线程私有的,与线程的生命周期同步。
用来描述Java方法执行的内存模型,每个方法被执行,JVM会在虚拟机栈中创建一个栈帧(Stack Frame)。
栈帧
一个线程包含多个栈帧。
每个栈帧包含局部变量表,操作数栈,动态链接,返回地址等。
局部变量表:顾名思义,变量的存储空间,方法的参数以及方法内部的变量都存在于此。
操作数栈:方法执行的过程中,会有各种字节码指令被压入和弹出操作数栈。
动态链接:支持方法调用过程中的动态连接(Dynamic Linking)。
Class 文件中存放了大量的符号引用,字节码中的方法调用指令就是以常量池中指向方法的符号引用作为参数。这些符号引用一部分会在类加载阶段或第一次使用时转化为直接引用,这种转化称为静态解析。另一部分将在每一次运行期间转化为直接引用,这部分称为动态连接。
返回地址:方法退出后需要返回到方法被调用的位置,程序才能继续执行。返回地址就是用来帮助当前方法恢复它的上层方法执行的状态
2.3 本地方法栈
和虚拟机栈基本相同,只不过是针对本地(native)方法,例如JIN可能接触本地方法多一些,有些虚拟机已经实现合二为一了。
2.4 堆
唯一目的,存放对象实例。
堆中内存可以划分为新生代(Young),老年代(Old),其中新生代又被划分为Eden和Survivor区。根据不同区使用不同的垃圾回收算法,提高垃圾回收效率。
2.5 方法区
JVM规范里面规定的一块运行时数据区。
存储已经被JVM加载的类的信息(版本、字段、方法、接口)、常量、静态变量、即时编译器编译后的代码和数据。