1.PC计数器:
Java虚拟机支持多条线程同时运行,每条Java虚拟机线程都有自己的pc寄存器,在任意时刻,一条Java虚拟机线程只会执行一个方法的代码。这个正在被线程执行的方法称为线程的当前方法。如果当前方法不是native的,pc寄存器保存Java虚拟机正在执行的字节码指令地址,如果该方法是native的,pc寄存器的值为undefined。
2.Java虚拟机栈(Java栈):
每条Java虚拟机线程都有自己私有的虚拟机栈,这个栈与线程同时创建,用于存储栈帧(栈帧可在堆中分配)。Java虚拟栈的作用:用于存储局部变量和一些尚未算好的结果,栈帧的出栈、入栈。
每一个栈帧相当于一个方法,入栈代表方法调用,出栈代码方法调用结束。main栈帧在最低层
3.Java堆:
堆是各个线程共享的运行时内存区域(是类实例和数组对象分配内存的区域),Java堆在虚拟机启动的时候创建,存储垃圾回收器所管理的各种对象。
4.方法区:
方法区是各个线程共享的运行时内存区域,存储类的结构信息,如运行时常量池、字段、和方法数据,构造函数和普通方法的字节码内容,还包括一些类、实例、接口初始化用到的特殊方法。方法区在虚拟机启动的时候创建,方法区是堆的逻辑组成部分。
运行时常量池:
运行时常量池是class文件中每一个类或者接口常量池表的运行表现形式,它包含若干不同的常量(从编译期可知的数值字面量到必须在运行期解析后才能获得的方法或字段引用)
每一个运行时常量池都是在Java虚拟机的方法区分配的,在加载类和接口到虚拟机后,就创建对应的运行时常量池。
5.本地方法栈:
本地方法栈支持native方法(使用Java以外的编写的方法)的执行,如果支持本地方法栈,该栈在线程创建的时候按线程分配
栈帧:是用来存储数据和部分过程结果的数据结构,处理动态链接、方法返回值和异常分派
栈帧随着方法的调用而创建,随着方法的结束而销毁。栈帧的存储空间由创建它的线程分配在Java虚拟机栈中,每一个栈帧都也自己的本地变量表(局部变量表)、操作数栈和指向当前方法所属类的运行时常量池的引用。
本地变量表和操作数栈的容量在编译期确定,并通过相关方法的code属性保存及提供给栈帧使用。(栈帧数据结构的大小仅仅取决于Java虚拟机的实现,实现者在调用方法时给它们分配内存)
在某条线程执行过程中的某个时间点上,当前正在执行的那个方法的栈帧叫当前栈帧,对应的方法叫当前方法,定义方法的类叫当前类。对局部变量表和操作数栈的各种操作,通常都指的是对当前栈帧的局部变量表和操作数栈所进行的操作。
当前方法执行结束,方法返回时,当前栈帧会返回此方法的执行结果给前一个栈帧,然后虚拟机会丢掉当前栈帧,使得前一个栈帧成为当前栈帧;当前方法调用新的方法,新的栈帧也会随之创建,并随着程序控制权的移交给新的方法,新的栈帧成为当前栈帧。
注:栈帧是线程本地私有的数据,不可能在一个栈帧中引用另外一个线程的栈帧。
(局部变量表)本地变量表:
每个栈帧内部都包含一组称为局部变量表的变量列表。栈帧中的局部变量表的长度由编译期决定,并存储于类或者接口的二进制表示之中,通过方法的code属性保存及提供给栈帧使用。