JVM 深入理解 (一) | JVM 的概述及 java 代码执行流程

  • JAVA编程
  • 2020-08-04 12:41:49
  • 浏览 74
简介没有特别幸运,那么请先特别努力,别因为懒惰而失败,还矫情地将原因归于自己倒霉。你必须特别努力,才能显得毫不费力。

Write once run anywhere

Java 之所以能成为跨平台的语言,其主要依赖与 JVM,只要在操作系统上安装有 JVM,通过 JVM 即可运行 Java 语言编译出来的字节码文件。一处编写,到处运行,完全依赖与 JVM 的支持,所以,也许 Java 并不是世界上最好的编程语言(不含 PHP ),但是 JVM 应该是世界上最好的虚拟机。

跨语言的虚拟机

JVM 运行的字节码文件都遵循着相应的 JVM 规范,如果有合适的编译器,遵循相应的 JVM 规范生成对应的字节码文件,JVM 是一样可以运行的,这也使得 JVM 成为一个跨语言的虚拟机成为可能。

JVM 整体结构

Class loader 最基本的功能就是将 Class 加载到 JVM 中,在加载过程中,Class loader 能够审查每个类应该由哪个 Class loader 加载,采用双亲委派模型来实现,除了加载外,class loader也负责将加载后的字节码重新解析成JVM同一要求的对象格式。

Runtime Data area 在执行的过程中,总会创建很多对象 必须有地方存放这些对象;还需要保存一些执行的状态,所以,必须有一个地方来保持执行的状态。 “地方” 指的就是内存区域, 程序运行起来之后, 就是一个动态的过程, 必须合理的划分内存区域, 来存放各种数据。

Execution Engine 执行引擎是 Java 虚拟机最核心的组成部分之一,“虚拟机”是一个相对于“物理机”的概念,这两种机器都具有执行代码的能力。其区别是物理机的执行引擎是直接建立在处理器、硬件、指令集和操作系统层面上的,而虚拟机的执行引擎则是由自己实现的,因此可以自行制定指令集和执行引擎的结构体系,并且能够执行那些不被硬件直接支持的指令集格式。

Java 代码执行流程

编写一个 Hello.java 文件

public class Hello {

    public static void main(String[] args) {
        int a = 1;
        int b = 2;
        int c = a + b;
    }

}

通过命令行输入编译命令,生成 Hello.class 文件

javac Hello.java

通过命令行输入查看 Hello.class 的 jvm 指令

javap -v Hello.class

输出代码如下,其中 code 部分就是 jvm 执行时候的指令

Classfile /F:/demo/out/production/demo01/com/_365d1/demo/Hello.class
  Last modified 2020-8-5; size 456 bytes
  MD5 checksum 2dba3366c299bd16497e4b547eca4902
  Compiled from "Hello.java"
public class com._365d1.demo.Hello
  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            // com/_365d1/demo/Hello
   #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               Lcom/_365d1/demo/Hello;
  #11 = Utf8               main
  #12 = Utf8               ([Ljava/lang/String;)V
  #13 = Utf8               args
  #14 = Utf8               [Ljava/lang/String;
  #15 = Utf8               a
  #16 = Utf8               I
  #17 = Utf8               b
  #18 = Utf8               c
  #19 = Utf8               SourceFile
  #20 = Utf8               Hello.java
  #21 = NameAndType        #4:#5          // "<init>":()V
  #22 = Utf8               com/_365d1/demo/Hello
  #23 = Utf8               java/lang/Object
{
  public com._365d1.demo.Hello();
    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 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/_365d1/demo/Hello;

  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_1
         1: istore_1
         2: iconst_2
         3: istore_2
         4: iload_1
         5: iload_2
         6: iadd
         7: istore_3
         8: return
      LineNumberTable:
        line 6: 0
        line 7: 2
        line 8: 4
        line 9: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  args   [Ljava/lang/String;
            2       7     1     a   I
            4       5     2     b   I
            8       1     3     c   I
}
SourceFile: "Hello.java"

Code 部分代码看起来很像汇编,这就很有意思了哈~~

文章评论