jvm1 class文件格式

  • java从编码到执行

  1. JIT是什么?Java程序最初是通过解释器进行解释执行的,当虚拟机发现某个方法或代码块运行的特别频繁时,会把这些代码认定为“热点代码”(Hot Spot Code)。为了提高热点代码的执行效率,在运行时,虚拟机会把这些代码编译成本地平台相关的机器码,并进行各种层次的优化,完成这个任务的编译器称为即时编译器(JIT编译器,不是Java虚拟机内必须的部分)。
  2. 解释器是一条一条的解释执行源语言。比如php,postscritp,javascript就是典型的解释性语言(直接执行)   编译器是把源代码整个编译成目标代码,执行时不再需要编译器,直接在支持目标代码的平台上运行,这样执行效率比解释执行快很多。比如C语言代码被编译成二进制代码(exe程序),在windows平台上执行。

  3. https://www.cnblogs.com/msymm/p/9395234.html

     

     

     

     

 

 

 

  • 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

 

 

 

  •  第四部分

 

  • 第五部分

 

posted @ 2020-04-07 23:59  zdcsmart  阅读(177)  评论(0编辑  收藏  举报