JVM虚拟机结构
JVM结构
JVM主要由类加载器子系统、内存空间(运行时数据区)、执行引擎及本地方法接口等组成。
其中内存空间(运行时数据区)由方法区、堆、JAVA栈、PC寄存器、本地方法栈组成。
在内存空间中,堆和方法区是所有JAVA线程共享的,JAVA栈、本地方法栈和PC寄存器则是每个线程私有的。
一、类加载子系统:在JVM启动时或者在类运行时将需要的class加载到JVM中。
二、内存空间(运行时数据区):是在JVM运行的时候操作所分配的内存区。
堆:用于存储实例对象及数组值(新生代和旧生代)。堆中有指向类数据的指针,该指针指向了方法区对应的类型信息。堆中还有可能存放了指向方法表的指针。
方法区:类型信息和类的静态变量都存储在方法区中。此外为了加快调用方法的速度,通常还会为每个非抽象类创建私有的方法表,方法表是一个数组,存放了实例可能被调用的实例方法的直接引用。在Sun JDK中,方法区对应了持久代(Permanent Generation),默认最小值为16MB,最大值为64MB。
方法区对于每个类存储了以下的数据:
1、类及其父类全限定名
2、类的类型(Class、Interface)
3、访问修饰符(public、abstract、final)
4、实现的接口的全限定名的列表
5、常量池
6、字段信息
7、方法信息
8、静态变量
9、ClassLoader引用
10、Class引用
JAVA栈:由栈帧组成,一个方法对应一个栈帧。调用方法时压入栈帧,方法返回时弹出栈帧并抛弃。JAVA栈的主要任务是存储方法参数、局部变量、中间运算结果并提供部分其他模块工作需要的数据。
栈帧分为3部分:局部变量区、操作数栈、帧数据区
局部变量区:用于存放方法中的局部变量和参数。
操作数栈:用于存放方法执行过程中产生的中间结果。
帧数据区:记录指向类的常量池的指针。
帮助方法的正常返回,包括恢复调用该方法的栈帧,设置PC寄存器指向调用方法对应的下一条指令,把返回值压入调用栈帧的操作数栈中。
记录异常表,发生异常时将控制权交由对应异常的catch子句,如果没有找到对应的catch子句,会恢复调用方法的栈帧并重新抛出异常。
本地方法区 :和JAVA栈的作用差不多,只不过为JVM使用到的native方法服务的。
PC寄存器:用于保存当前线程执行的内存地址。由于JVM程序是多线程执行的(线程轮流切换),所以为了保证线程切换回来后,还能恢复到原先状态,就需要一个独立的计数器,记录之前中断的地方,可见程序计数器也是线程私有的。
三、执行引擎:负责执行class文件中包含的字节码指令。
四、本地方法接口:主要是调用C或C++实现的本地方法及返回结果。