JVM

56 阅读2分钟

1 架构

image.png

简单理解:
线程独占区:用来存放执行程序的数据 线程共享区:用来存放对象和类信息等

2 虚拟机栈:

image.png

3 执行引擎

通用虚拟机指令执行流程:

  • 取指令,其中指令来源于内存
  • 译码,决定指令类型(执行何种操作)。另外译码的过程要包括从内存中取操作数
  • 执行。指令译码后,被虚拟机执行(其实最终都会借助于物理机资源)
  • 存储计算结果

虚拟机的分类

  • 基于栈

    • 可移植
    • 速度慢,完成功能指令多
  • 基于寄存器

    • 依赖寄存器,不容易移植
    • 速度快,完成功能指令少

例如执行”a = b + c”:
基于寄存器虚拟机执行该操作只有一条指令:

I1: add a, b, c

在基于栈的虚拟机上字节码指令如下所示:

I1: LOAD C   
I2: LOAD B   
I3: ADD   
I4: STORE A

基于栈的虚拟机:
基于栈的虚拟机有一个操作数栈的概念,虚拟机在进行真正的运算时都是直接与操作数栈(operand stack)进行交互,不能直接操作内存中数据),也就是说不管进行何种操作都要通过操作数栈来进行,即使是数据传递这种简单的操作。可以无视具体的物理架构。

查看字节码指令

public class ByteCodeTest {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }

    public int add() {
        int b = 2;
        int c = 10;
        int a = b + c;
        return a;
    }
    public int add2(int d) {
        int b = 2;
        int c = 10;
        int a = b + c;
        return a + d;
    }
}
public int add();
    descriptor: ()I
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=2, locals=4, args_size=1
         0: iconst_1        //  把1值推入操作数栈
         1: istore_1        // 栈顶出栈并保存到局部变量表Slot1
         2: bipush          // 把10值推入操作数栈
         4: istore_2          // 栈顶出栈并保存到局部变量表Slot2
         5: iload_1         //局部变量表Slot1入栈
         6: iload_2         //局部变量表Slot2入栈
         7: iadd            // 将两个栈顶元素出栈,相加,并把结果入栈
         8: istore_3        // 栈顶出栈并保存到局部变量表Slot3
         9: iload_3         //局部变量表Slot3入栈
        10: ireturn
      LineNumberTable:
        line 11: 0
        line 12: 2
        line 13: 5
        line 14: 9
}
 public int add2(int);
    descriptor: (I)I
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=2, locals=5, args_size=2
         0: iconst_2
         1: istore_2
         2: bipush        10
         4: istore_3
         5: iload_2
         6: iload_3
         7: iadd
         8: istore        4
        10: iload         4
        12: iload_1
        13: iadd
        14: ireturn
      LineNumberTable:
        line 18: 0
        line 19: 2
        line 20: 5
        line 21: 10
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      15     0  this   LByteCodeTest;
            0      15     1     d   I
            2      13     2     b   I
            5      10     3     c   I
           10       5     4     a   I

49c64ad423feceafced8c945d981b596.jpg image.png 

参考

# JVM整体内存结构的图解,直观明了