Java内存区域就是Java运行时数据区
程序计数器是什么:可以看作是当前线程所执行的字节码的行号指示器
程序计数器的作用:
栈是 JVM 运行时数据区域的一个核心,除了一些 Native 方法是本地方法栈实现的
其他所有 Java 方法的调用都是由虚拟机栈协助执行的
虚拟机栈由一个个栈帧组成,栈帧的组成有:
接下来我们一个个说明他们的作用
局部变量表用来存放:
局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。在Java程序被编译成Class文件时,就在方法的Code属性的max_locals数据项中确定了该方法所需要分配的最大局部变量表的容量。
操作数栈也是栈结构,可以简单的理解它的作用就是方法中变量进行运算
主要服务一个方法调用另一个方法的场景
动态链接的作用就是为了将符号引用转换为直接引用
无论方法采用何种方式退出,在方法退出后都需要返回到方法被调用的位置,程序才能继续执行,方法返回时可能需要在当前栈帧中保存一些信息,用来帮他恢复它的上层方法执行状态。
方法退出过程实际上就等同于把当前栈帧出栈,因此退出可以执行的操作有:恢复上层方法的局部变量表和操作数栈,把返回值(如果有的话)压入调用者的操作数栈中,调整PC计数器的值以指向方法调用指令后的下一条指令。
一般来说,方法正常退出时,调用者的PC计数值可以作为返回地址,栈帧中可能保存此计数值。而方法异常退出时,返回地址是通过异常处理器表确定的,栈帧中一般不会保存此部分信息。
调用Native方法
堆是线程共享的。
JDK7版本以及JDK7版本之前,堆内存通常分为下面三部分:
下图中的Eden区、两个S区S0、S1都属于新生代
JDK8版本之后永久代被元空间取代,元空间使用的是直接内存
元空间,不再与堆连续,而是直接存在于本地内存,也就是机器的内存。理论上机器内存有多大,元空间就有多大。
在之前的版本中,字符串常量池存在于永久代中,在大量使用字符串的情况下,容易出现OOM异常,此外JVM加载的class总数、方法的大小等都很难确定,因此对永久代大小难以确定。
当虚拟机要使用一个类时,它需要读取并解析 Class 文件获取相关信息,再将信息存入到方法区。方法区会存储已被虚拟机加载的 类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据。
主要是存放一个类的:
基础信息
常量池
字段
方法
法区会存储已被虚拟机加载的 类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据。
主要是存放一个类的:
基础信息
常量池
字段
方法
属性