2

图解JVM整体结构、执行流程以及两种架构模型,你学会了吗?

 2 years ago
source link: https://www.51cto.com/article/687384.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

 JVM整体结构 

图解JVM整体结构、执行流程以及2种架构模型,你学会了吗? 
  • HotSpot VM 是目前市面上高性能虚拟机的代表作之一。
  • 方法区和堆:多线程共享
  • 虚拟机栈、本地方法栈、程序计数器:每个线程独有一份
  • 执行引擎:包含三部分:解释器,及时编译器(后端编译器),垃圾回收器
  • 它采用解释器与即时编译器并存的架构。
  • 在今天,Java 程序的运行性能早已脱胎换骨,已经达到了可以和 C/C++ 程序一较高下的地步。 
图解JVM整体结构、执行流程以及2种架构模型,你学会了吗? 

Java 代码执行流程 

图解JVM整体结构、执行流程以及2种架构模型,你学会了吗? 

只是能生成被 Java 虚拟机所能解释的字节码文件,那么理论上就可以自己设计一套代码了

解释器:保证相应时间,负责解释执行的速度

JIT编译器:负责编译的性能,针对字节码指令,热点代码,放在方法区缓存起来,下次遇见直接变成二进制指令

JVM 的架构模型

Java 编译器输入的指令流基本上是一种基于栈的指令集架构,另外一种指令集架构则是基于寄存器的指令集架构。

具体来说:这两种架构之间的区别:

基于栈式架构

  • 设计和实现更简单,适用于资源受限的系统;
  • 避开了寄存器的分配难题:使用零地址指令方式分配。
  • 指令流中的指令大部分是零地址指令,其执行过程依赖于操作栈。指令集更小,编译器容易实现。
  • 不需要硬件支持,可移植性更好,更好实现跨平台

基于寄存器架构

  • 典型的应用是 x86 的二进制指令集:比如传统的 PC 以及 Android 的 Davlik 虚拟机。
  • 指令集架构则完全依赖硬件,可移植性差
  • 性能优秀和执行更高效
  • 花费更少的指令去完成一项操作。
  • 在大部分情况下,基于寄存器架构的指令集往往都以一地址指令、二地址指令和三地址指令为主,而基于栈式架构的指令集却是以零地址指令为主

同样执行2+3这种逻辑操作,其指令分别如下:

基于栈的计算流程(以Java虚拟机为例):

iconst_2 // 常量2入栈 
istore_1 
iconst_3 // 常量3入栈 
istore_2 
iload_1 
iload_2 
iadd    //常量2/3出栈,执行相加 
istore_0 // 结果5入栈 

而基于寄存器的计算流程

mov eax,2 //将eax寄存器的值设为 
1add eax,3 //使eax寄存器的值加3 

字节码反编译

我们编写一个简单的代码,然后查看一下字节码的反编译后的结果

public class StackStruTest { 
  public static void main(String[] args) { 
    int i = 2 + 3; 
  } 
} 

然后我们找到编译后的 class 文件,使用下列命令进行反编译

javap -v(verbose) StackStruTest.class 

得到的文件为:

public static void main(java.lang.String[]); 
    descriptor: ([Ljava/lang/String;)V 
    flags: ACC_PUBLIC, ACC_STATIC 
    Code: 
      stack=2, locals=4, args_size=1 
         0: iconst_2 
         1: istore_1 
         2: iconst_3 
         3: istore_2 
         4: iload_1 
         5: iload_2 
         6: iadd 
         7: istore_3 
         8: return 
      LineNumberTable: 
        line 9: 0 
        line 10: 2 
        line 11: 4 
        line 12: 8 
      LocalVariableTable: 
        Start  Length  Slot  Name   Signature 
            0       9     0  args   [Ljava/lang/String; 
            2       7     1     i   I 
            4       5     2     j   I 
            8       1     3     k   I 
  

由于跨平台性的设计,Java 的指令都是根据栈来设计的。

不同平台 CPU 架构不同,所以不能设计为基于寄存器的。

优点是跨平台,指令集小,编译器容易实现

缺点是性能下降,实现同样的功能需要更多的指令。

时至今日,尽管嵌入式平台已经不是 Java 程序的主流运行平台了(准确来说应该是 HotSpotVM 的宿主环境已经不局限于嵌入式平台了),那么为什么不将架构更换为基于寄存器的架构呢?

总结:因为已经够用了

执行性能比寄存器差


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK