JVM深入原理(三+四):JVM组成和JVM字节码文件
目录
3. JVM组成
3.1. 组成-运行时数据区
3.2. 组成-类加载器
3.3. 组成-执行引擎
3.4. 组成-本地接口
4. JVM字节码文件
4.1. 字节码文件-组成
4.1.1. 组成-基础信息
4.1.1.1. 基础信息-魔数
4.1.1.2. 基础信息-主副版本号
4.1.2. 组成-常量池
4.1.3. 组成-方法
4.1.3.1. 方法-工作流程
4.1.4. 组成-字段
4.1.5. 组成-属性
4.2. 字节码文件-查看工具
4.2.1. javap
4.2.2. jclasslib
4.2.3. 阿里Arthas
3. JVM组成
- JVM组成结构
3.1. 组成-运行时数据区
- 运行时数据区域的作用:负责管理JVM运行时使用到的内存,比如创建对象和销毁对象
- 运行时数据区结构
3.2. 组成-类加载器
- 类加载器的作用:将.class字节码文件加载到运行时数据区,JVM分配在堆中分配一块空间存放字节码文件中的类和接口
3.3. 组成-执行引擎
- 执行引擎的作用:将字节码文件中的指令翻译成机器码,同时使用及时编译器优化性能
- 执行引擎的组成及作用:
-
- 即时编译器:将热点代码的机器码存入操作系统内存
- 解释器:实时翻译字节码中的指令为机器码
- 垃圾回收器:回收未被引用的对象
3.4. 组成-本地接口
- 本地接口:调用本地已实现的接口,如JVM中由c,c++提供的方法
4. JVM字节码文件
4.1. 字节码文件-组成
4.1.1. 组成-基础信息
- 基础信息作用:包含了魔数,字节码对应Java版本号,访问标识,类/父类/接口的索引
4.1.1.1. 基础信息-魔数
- 如何确定文件类型?
-
- 文件是通过文件的前几个字节(称为文件头)来确定文件的类型,而不是通过文件扩展名来确定
- 软件要打开文件首先要校验文件头,如果不匹配则报错
- 常见文件的文件头:
- 魔数的作用:作为字节码文件的头文件标识,固定为0xCAFEBABE
4.1.1.2. 基础信息-主副版本号
- 主版本号的作用:用来标识大版本号,判断当前字节码文件对应Java版本号是否与当前版本号兼容,一般是大版本号兼容小版本号
- 副版本号的作用:主版本号相同时区分不同小版本的标识
- JDK1对应45,JDK2对应46,JDK6对应50,JDK8对应52
4.1.2. 组成-常量池
- 常量池的作用:保存字符串常量,类名,接口名,字段名,用于字节码指令的符号引用,可以避免相同内容的重复定义
- 常量池工作流程:常量池中的常量都有一个从1开始的编号,在字节码指令中通过编号可以快速找到对应的数据,这个过程叫做符号引用
-
4.1.3. 组成-方法
- 方法的作用:存放字节码指令,其Code属性存放字节码指令具体内容
4.1.3.1. 方法-工作流程
- 方法的工作流程:按照字节码指令从上至下依次执行,需要用到虚拟机栈中的两个区域:操作数栈和局部变量表
-
- iconst_0:将常量0压入栈中.
- istore_1:将栈中的数据弹出存入局部变量表1号位置.
- iload_1:将局部变量表1号数据拷贝压入栈中.
- iconst_1:将常量1压入栈中.
- iadd:将栈中数据弹出,执行完累加操作后,把结果压入栈中.
- istore_2:将栈中的数据弹出存入局部变量表2号位置.
-
- iconst_0:将常量0压入栈中.
- istore_1:将栈中的数据弹出存入局部变量表1号位置.
- iload_1:将局部变量表1号数据(0)拷贝压入栈中.
- iinc 1 by 1:将局部变量表1号数据加1
- istore_1:将栈中的数据(0)弹出覆盖局部变量表1号位置.
- return:返回结果0,
-
- ++i和i++的区别:
-
-
- ++i:先执行iinc后执行iload,先加后入再弹,最终数据+1
- i++:先执行iload后执行iinc,先如后加再弹,最终数据不变
-
-
- i++; i+=1; i=i+1; 的执行效率:
-
-
- i++; i+=1;:仅有一行iinc运算,效率高
- i=i+1;:有ioad,iconst,iadd,istore四行运算,效率低
-
4.1.4. 组成-字段
- 字段的作用:保存类中定义的属性信息,包括属性的访问修饰符、属性名称、属性类型等等
4.1.5. 组成-属性
- 属性的作用:保存类的相关属性,比如源代码文件名,内部类的列表等等
4.2. 字节码文件-查看工具
- 字节码文件中保存的是Java代码编译后的内容,并以二进制方式存储,无法直接用记事本打开
4.2.1. javap
- javap的作用:javap是JDK自带的反编译工具,可以通过控制台查看字节码文件的内容.
- javap的适用场景:javap使用方便,在jdk环境中即可使用,适合在服务器上查看字节码文件
- javap的用法:
-
- 查看指定的字节码文件:javap -v xx.class > xx.txt,字节码文件和输出位置需要指定全路径名
- javap所有用法:
4.2.2. jclasslib
- Githubt地址:https://github.com/ingokegel/jclasslib
- jclasslib介绍:jclasslib可以直观地看到字节码文件各个部分
- jclasslib-idea插件版使用
-
- idea下载插件jclasslib
- 点击Java源代码文件后点击视图展示字节码文件
- 修改Java源码后需要进行一次编译(ctrl+shift+f9)才能看到修改后的字节码文件
-
4.2.3. 阿里Arthas
- Arthas介绍:Arthas是一款线上监控诊断产品,通过全局视角实时查看应用load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,大大提升线上问题排查效率。
- Arthas官网:简介 | arthas
- Arthas使用:
-
- 启动Arthas:java -jar arthas-boot.jar --telnet-port 9998 --http-port -1
- 加载运行时字节码到指定目录:dump -d D:/arthas/data/ org.pickstar.arthas.Demo
- 反编译运行时字节码为Java源码:jad org.pickstar.arthas.Demo
-
-