-
java从编码到执行
- JIT是什么?Java程序最初是通过解释器进行解释执行的,当虚拟机发现某个方法或代码块运行的特别频繁时,会把这些代码认定为“热点代码”(Hot Spot Code)。为了提高热点代码的执行效率,在运行时,虚拟机会把这些代码编译成本地平台相关的机器码,并进行各种层次的优化,完成这个任务的编译器称为即时编译器(JIT编译器,不是Java虚拟机内必须的部分)。
-
解释器是一条一条的解释执行源语言。比如php,postscritp,javascript就是典型的解释性语言(直接执行) 编译器是把源代码整个编译成目标代码,执行时不再需要编译器,直接在支持目标代码的平台上运行,这样执行效率比解释执行快很多。比如C语言代码被编译成二进制代码(exe程序),在windows平台上执行。
-
jvm与java无关 只与class文件格式有关 如scala、kotlin、groovy等语言编写的代码最终也变为符合class格式的二进制流
-
jvm是一种规范 https://docs.oracle.com/en/java/javase/13/
- jvm是虚构出来的一台计算机 有字节码指令集 内存管理
-
常见的JVM实现:
-
Hotspot Jrockit(已经合入Hotspot中) TaobaoVM LiquidVM azul zing(垃圾回收速度快 停顿短)
-
-
jvm jre=jvm+core lib jdk=jre+development kit
-
class文件格式
-
public class T0100_ByteCode01 {
}
在idea 下载BinEd插件 打开该类的class的文件 用16进制显示如下图所示
- 第一部分
Magic Number: CA FE BA BE 4个字节 代表class格式标识
Minor Version: 00 00 2个字节 小版本号
Major Version: 00 34 2个字节 大版本号 52
constant_pool_count: 00 10 2个字节 代表常量池里的常量个数 16-1 (常量池里的编号从1开始)
1 用javap命令查看class文件
MacBook-Pro c1_bytecode % javap -v T0100_ByteCode01.class
Classfile /Users/zhangdacheng/Desktop/code/JVM/out/production/JVM/com/mashibing/jvm/c1_bytecode/T0100_ByteCode01.class
Last modified 2020年4月9日; size 333 bytes
SHA-256 checksum 7ed16a34617c5d23194c075dca551cc3abae115e5cc7b2165cca6030c952e408
Compiled from "T0100_ByteCode01.java"
public class com.mashibing.jvm.c1_bytecode.T0100_ByteCode01
minor version: 0
major version: 52
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #7 // com/mashibing/jvm/c1_bytecode/T0100_ByteCode01
super_class: #2 // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
Constant pool:
#1 = Methodref #2.#3 // java/lang/Object."<init>":()V
#2 = Class #4 // java/lang/Object
#3 = NameAndType #5:#6 // "<init>":()V
#4 = Utf8 java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Class #8 // com/mashibing/jvm/c1_bytecode/T0100_ByteCode01
#8 = Utf8 com/mashibing/jvm/c1_bytecode/T0100_ByteCode01
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Lcom/mashibing/jvm/c1_bytecode/T0100_ByteCode01;
#14 = Utf8 SourceFile
#15 = Utf8 T0100_ByteCode01.java
{
public com.mashibing.jvm.c1_bytecode.T0100_ByteCode01();
descriptor: ()V
flags: (0x0001) 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/mashibing/jvm/c1_bytecode/T0100_ByteCode01;
}
SourceFile: "T0100_ByteCode01.java"
2 用Idea插件 JclassLib
点到java文件上 点击头栏上的view 选中show bytecode with jclasslib
注意access flags为0x0021
This class: cp_info#7 该类名存在常量池第七项
Super class: cp_info#2 该类名存在常量池第2项
Interfaces count
Fields count
Methods count
Attribute count
-
constant pool
常量池中的常量类型
utf8代表字符串 class_info 几种数据类型 Methodref_info等 18项
分析一下Methodref_info
0a 0002 0003: oa表示10 代表method_info 0002代表指向常量池的2 0003代表指向常量池的3
07 0004 :07表示class_info 0004代表指向常量池的4
0c 0005 0006:0c表示NameAndtype_info 指向5和6
01 0010代表 utf8_info 长度为16 6A 61 76 ......等16个字节表示 java/lang/Objecss
01 0006代表 utf8_info 长度为16 3C 69 ..等6个字节表示 <init>
。。略
class name 指向常量池 2 。常量池2的类型是Class_info,其指向常量池4 即class的限定名为java/lang/Object
name and type指向常量池3。常量池3的类型是NameAndType_info,其name指向了常量池5 即init--构造方法。 descriptor指向了6 ()V--描述符 该方法无参数 返回值v代表无参数。
即指向了object的无参构造方法!!!
- 第二部分
access只需要两个字节 做与运算 可以代表很多内容
0x0001 | 0x0020 = 0x0021
- 第三部分
aload_0用0x2a代表--java指令 把this压入栈中
invokespecial #1 用b7 (0001引用常量池 即Object ) 调用构造方法
return b1 这代表引用了Object的构造方法
-----2a b7 0001 b1
- 第四部分
- 第五部分