JVM体系结构篇之JVM的整体结构

  • Post author:
  • Post category:其他

在这里插入图片描述

上图为JVM在服务器上的整体结构图,从上到下简单介绍一下。

  • .class:由.java(也可是其他文件)文件通过编译器编译得到字节码文件。

  • 类加载器子系统:将磁盘上的字节码文件转换为instanceKlass 保存在运行时数据区(方法区)中,一个字节码文件通过类加载子系统添加到运行时数据区需要经过加载、连接、初始化三个步骤。

  • 运行时数据区:JVM在执行java程序的过程中所管理的内存(会根据其职责或分为多个区域)。

  • 执行引擎:将程序计数器中记录的字节码指令转换为机器语言。与程序计数器的双向箭头是由于,执行引擎在程序计数器中获取了某条指令执行后会将程序计数器中的值改为下条指令地址是双向的;与本地接口库的单向箭头代表,可能程序计数器中的某条指令代表调用Native方法,此时执行引擎解释执行时需要访问本地接口库。

  • 本地方法接口库:存放了java代码中定义的Native方法接口。本地方法在本地方法栈中的压栈出栈操作对应了本地方法栈和本地接口库的双向箭头,本地方法的执行无需程序计数器和执行引擎协助。程序计数器记录的是方法的字节码指令地址,执行引擎也只能解释执行字节码指令,二者都是JVM层面的抽象概念,而Native并不是java代码编写的也不存在字节码指令,所以Native方法的执行直接由原生的CPU上真正的PC寄存器负责。

  • 本地方法库:存储了本地接口的方法实现。

  • 附:附带一个面试题,如果执行Native方法时,程序计数器不存储值,那么线程切换后如何恢复原位继续执行?
    这里的“pc寄存器”(即程序计数器)是在抽象的JVM层面上的概念——当执行Java方法时,这个抽象的“pc寄存器”存的是Java字节码的地址。实现上可能有两种形式,一种是相对该方法字节码开始处的偏移量,叫做bytecode index,简称bci;另一种是该Java字节码指令在内存里的地址,叫做bytecode pointer,简称bcp。对native方法而言,它的方法体并不是由Java字节码构成的,自然无法应用上述的“Java字节码地址”的概念。所以JVM规范规定,如果当前执行的方法是native的,那么pc寄存器的值未定义——是什么值都可以。上面是JVM规范所定义的抽象概念,那么实际实现呢?
    Java线程总是需要以某种形式映射到OS线程上。映射模型可以是1:1(原生线程模型)、n:1(绿色线程 / 用户态线程模型)、m:n(混合模型)。
    以HotSpot VM的实现为例,它目前在大多数平台上都使用1:1模型,也就是每个Java线程都直接映射到一个OS线程上执行。此时,native方法就由原生平台直接执行,并不需要理会抽象的JVM层面上的“pc寄存器”概念——原生的CPU上真正的PC寄存器是怎样就是怎样。就像一个用C或C++写的多线程程序,它在线程切换的时候是怎样的,Java的native方法也就是怎样的。

语雀地址:https://www.yuque.com/yangxiaofei-vquku/wmp1zm/udvme7


版权声明:本文为yangxiaofei_java原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。