JVM学习–运行时数据区
PC寄存器
Java虚拟机可以同时支持许多执行线程。 每个Java虚拟机线程都有自己的pc(程序计数器)寄存器。用于指示本线程所执行字节码的行号,字节码解释器就是通过改变这个值来选择下一条要执行的字节码指令。
注意这里是虚拟机的PC寄存器,指示的是字节码行号,机器本身也会有PC寄存器,指示的是机器语言的行号。
这个内存区块不会抛出OutOfMemoryError异常。
Java虚拟机栈
Java虚拟机栈是线程私有的内存,生命周期的线程的一样。Java虚拟机栈描述的是Java方法执行的栈帧,每个方法执行都会创建一个栈帧用于存储局部变量,操作数栈,动态链接,方法出口等信息。每个方法从调用到执行完成,都会经历一个栈帧从虚拟机栈中入栈和出栈的过程。
- 如果请求的栈深度超过虚拟机规定的栈深度,就会抛出StackOverflowError异常;
- 如果虚拟机可以支持动态扩展,如果扩展时无法申请到足够的内存,将会抛出OutOfMemoryError异常。
方法区
方法区是线程共享的内存区域。用于存放被虚拟机加载的类信息,常量,静态变量,编译器编译后的代码等数据。
方法区是虚拟机的规范,而永久代是虚拟机实现方法区的方式。由于永久代存在内存溢出的问题,在JDK8开始,HotSpot虚拟机去掉了永久代,并使用MetaSpace(元空间)来代替,其使用机器的物理内存。
当方法区如果不能满足内存分配时将会抛出OutOfMemoryError异常。
堆
Java堆是线程共享的一块区域,所有的对象实例都是放在堆中。
Java堆是垃圾收集的主要区域,为了提高垃圾收集的效率,Java堆还分为以上的几块区域。当堆内存不足时,将会抛出OutOfMemoryError异常。
本地方法栈
本地方法栈和虚拟机栈的作用一样,也会抛出StackOverflowError异常和OutOfMemoryError异常。区别是其是执行本地方法(Native修饰的方法)所产生的栈帧。Native方法使用C或者C++语言编写的代码。
运行时常量池
运行时常量池是方法区的一部分,Class文件中除了有类的版本,字段,方法,接口等描述信息,还有运行时常量池(Runtime Constan Pool).用于存放编译期生成的各种字面量和符号引用。
- 字面量:文本字符串,声明为final的常量等值。
- 符号引用:
- 类和接口的全限定名称
- 字段的名称和描述符
- 方法的名称和描述符