chapter01 jvm整体结构、架构模型与指令集

1.JVM推荐书籍

2.JVM跨语言的平台

kotlin、clojure、groovy、Scala等语言经过各自编译器编译之后,只要编译后的字节码文件严格满足java虚拟机字节码规范,以上语言均能在jvm中运行。因此,从一定程度上说,jvm已成为一个框语言的平台。

3.jvm整体结构

以下主要是针对 Hotspot 虚拟机

可以发现 方法区与堆区使用同一颜色进行标记,这是因为这两个区域是多线程共享的区域;而Java栈(java虚拟机栈)、本地方法栈与程序计数器是不同线程都具有的。

注意:java栈是以前叫法,目前叫虚拟机栈

执行引擎中具体又可以分为三部分内容,看下图。

以下是详细结构图:

class文件经过类加载子系统加载,在加载子系统中进行 加载、连接、初始化后,加载到内存中成功一个class对象。java代码加载到java内存中后,就要解释运行了,解释运行就需要用到执行引擎。

执行引擎中有三部分:解释器,JIT(即时编译器) 和 GC 。

解释器是class文件一上到执行引擎就逐行执行;为了提高代码执行效率,对于反复执行的热点代码,希望能提前编译出来,那么就去使用JIT(即时编译)进行编译,jit在把热点代码编译成机器指令时就缓存起来了放在方法区中。

4.java代码执行流程

5.jvm架构模型

栈式架构:指令集是以1个字节位基础(8位)进行对齐设计
寄存器式架构:指令集是以双字节(16位)进行对齐设计,因此寄存器架构能花费更少的指令集去做操作

下面使用反编译class字节码来了解指令集。

6.指令集

源代码:

public class Main{

    public static void main(String[] args) {

        int i = 2 + 3;

    }

}

反编译class:
javap -v Main.class

chapter01/out/production/chapter01/Main.class
  Last modified 2020-2-17; size 379 bytes
  MD5 checksum 76ad909d793e7c5dec56706d8628118e
  Compiled from "Main.java"
public class Main
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #3.#19         // java/lang/Object."<init>":()V
   #2 = Class              #20            // Main
   #3 = Class              #21            // java/lang/Object
   #4 = Utf8               <init>
   #5 = Utf8               ()V
   #6 = Utf8               Code
   #7 = Utf8               LineNumberTable
   #8 = Utf8               LocalVariableTable
   #9 = Utf8               this
  #10 = Utf8               LMain;
  #11 = Utf8               main
  #12 = Utf8               ([Ljava/lang/String;)V
  #13 = Utf8               args
  #14 = Utf8               [Ljava/lang/String;
  #15 = Utf8               i
  #16 = Utf8               I
  #17 = Utf8               SourceFile
  #18 = Utf8               Main.java
  #19 = NameAndType        #4:#5          // "<init>":()V
  #20 = Utf8               Main
  #21 = Utf8               java/lang/Object
{
  public Main();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 1: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   LMain;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=2, args_size=1
         0: iconst_5      // pc寄存器 地址0  这里编译直接得到5了
         1: istore_1      // pc寄存器 地址1
         2: return        // pc寄存器 地址2
      LineNumberTable:
        line 4: 0
        line 6: 2
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       3     0  args   [Ljava/lang/String;
            2       1     1     i   I
}
SourceFile: "Main.java"

  

 

源代码:
public static void main(String[] args) {
    // int i = 2 + 3;
    int i = 2;
    int j = 3;
    int k = i + j;
}

反编译:javap -v Main.class

chapter01/out/production/chapter01/Main.class
  Last modified 2020-2-17; size 421 bytes
  MD5 checksum a8764d11c1ae83f17d80270b05dbb2c9
  Compiled from "Main.java"
public class Main
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #3.#21         // java/lang/Object."<init>":()V
   #2 = Class              #22            // Main
   #3 = Class              #23            // java/lang/Object
   #4 = Utf8               <init>
   #5 = Utf8               ()V
   #6 = Utf8               Code
   #7 = Utf8               LineNumberTable
   #8 = Utf8               LocalVariableTable
   #9 = Utf8               this
  #10 = Utf8               LMain;
  #11 = Utf8               main
  #12 = Utf8               ([Ljava/lang/String;)V
  #13 = Utf8               args
  #14 = Utf8               [Ljava/lang/String;
  #15 = Utf8               i
  #16 = Utf8               I
  #17 = Utf8               j
  #18 = Utf8               k
  #19 = Utf8               SourceFile
  #20 = Utf8               Main.java
  #21 = NameAndType        #4:#5          // "<init>":()V
  #22 = Utf8               Main
  #23 = Utf8               java/lang/Object
{
  public Main();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 1: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   LMain;

  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    // 定义常量2
         1: istore_1    // 常量2保存在索引1位置
         2: iconst_3    // 定义常量3
         3: istore_2    // 常量3保存在索引2位置
         4: iload_1     // 加载索引1位置数值
         5: iload_2     // 加载索引2位置数值
         6: iadd        // 求和
         7: istore_3    // 值存储在索引3
         8: return      // 返回
      LineNumberTable:
        line 5: 0
        line 6: 2
        line 7: 4
        line 8: 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
}
SourceFile: "Main.java"

 

jvm指令集: https://blog.csdn.net/zhangpan19910604/article/details/52254053

posted @ 2020-02-18 09:24  margo  阅读(204)  评论(0)    收藏  举报