Java虚拟机结构

运行时数据区

PC寄存器

每一条Java虚拟机线程都有自己的pc寄存器。在任意时刻,一条Java虚拟机线程只会执行一个方法的代码,这个正在被线程执行的方法称为该线程的当前方法。如果这个方法不是native的,那pc寄存器就保存Java虚拟机正在执行的字节码指令的地址,如果该方法是native的,那pc寄存器的值是undefined。

Java虚拟机栈

每一条Java虚拟机线程都有自己私有的Java虚拟机栈,这个栈与线程同时创建,用于存储栈帧。Java虚拟机栈的作用与传统语言中的栈非常类似,用于存储局部变量与一些尚未算好的结果。

Java堆

堆是供各个线程共享的运行时内存区域,也是供所有类实例和数组对象分配内存的区域。Java堆在虚拟机启动的时候就被创建。

方法区

方法区是可供各个线程共享的运行时内存区域。它存储了每一个类的结构信息,例如,运行时常量池、字段和方法数据、构造函数和普通方法的字节码内容,还包括一些在类、实例、接口初始化时用到的特殊方法。

方法区在虚拟机启动的时候创建,虽然方法区是堆的逻辑组成部分,但是简单的虚拟机实现可以选择在这个区域不实现垃圾收集策略。

运行时常量池

运行时常量池是class文件中每一个类或接口的常量池表的运行时表示形式,它包含了若干种不同的常量,从编译期可知的数值字面量到必须运行期解析后才能获得的方法或字段引用。

每一个运行时常量池都在Java虚拟机的方法区中分配,在加载类和接口到虚拟机后,就创建对应的运行时常量池。

本地方法栈

栈帧

局部变量表

每个栈帧内部都包含一组称为局部变量表的变量列表。栈帧中局部变量表的长度由编译期决定,并且存储于类或接口的二进制表示之中,即通过方法的code属性保存及提供给栈帧使用。

操作数栈

每个栈帧内部都包含一个称为操作数栈的后进先出栈。栈帧中操作数栈的最大深度由编译期决定,并且通过方法的code属性保存及提供给栈帧使用。

动态链接

每个栈帧内部都包含一个指向当前方法所在类型的运行时常量池的引用,以便对当前方法的代码实现动态链接。

特殊方法

在Java虚拟机层面上,Java编程语言中的构造器是以一个名为的特殊实例初始化方法的形式出现的。这个方法的名称是由编译器命名的,因为它并非一个合法的Java方法名字,不可能通过程序编码的方式实现。

实例初始化方法只能在实例的初始化期间,通过Java虚拟机的invokespecial指令来调用,而且只能在尚未初始化的实例上调用该指令。

一个类或者接口最多可以包含不超过一个类或接口的初始化方法,类或者接口就是通过这个方法完成初始化的。这个方法是一个不包含参数的、返回类型为void的方法,名为。

当class文件的版本号不小于51.0时,方法要想成为类或接口的初始化方法,必须设置ACC_STATIC标志[Java SE 7中新增规定]。

原文地址:https://www.cnblogs.com/lucare/p/8679140.html