JVM 深入理解 (一) | JVM 的概述及 java 代码执行流程
- JAVA编程
- 2020-08-04 12:41:49
- 浏览 249
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 部分代码看起来很像汇编,这就很有意思了哈~~