本文最后更新于:2024年4月22日 下午
了解JVM整体架构图,javac编译器编译步骤,class文件的解读,字节码指令是什么以及常见的字节码有哪些
概念:广义上的JVM是指一种规范,狭义上的JVM指的是Hotspot类的虚拟机实现
Java语言与JVM的关系:Java语言编写程序生成class字节码在JVM虚拟机里执行。其他语言也可以,比如 kotlin、Groovy
学习流程:类加载子系统 –> 运行时数据区 –> 一个对象的一生–> GC垃圾收集器
知识体系
JVM整体学习流程
- 字节码引出JVM基础知识
- 类的加载过程
- 运行时内存数据
- 对象内存布局
- 执行引擎
- 垃圾回收
- JVM性能监控
- 性能调优案例
字节码篇
什么是字节码指令?
Java虚拟机的指令是由一个字节长度
的、代表着某种特定操作含义的操作码
(opcode),以及其后跟随零至多个
代表此操作所需参数的操作数
(operand)
字节码案例
案例1
通过idea插件jclasslib观察字节码文件
Integer.valueOf里面回去调用 IntegerCache缓存对象
案例2
str1不和str2相等的原因在于,str1的对象是由两个StringBuilder对象转化使用append拼接,最后调用StringBuilder的toString,而toString里面使用的值又是StringBuilder对象的值新new一个对象的,而str2是直接在堆中常量对象,二者地址自然不对等
案例3
加入 str1.intern(); 就是true jdk6还事false,jdk8后是true,因为jdk8后的常量池也在堆中,此时通过 str1.intern();会将常量池改对象的地址指向堆中的地址
如何解读class文件?
.class文件以16进制存储的
如上,.class
文件开头的4个字节cafe babe
称之为 魔数,0000是编译器jdk版本的次版本号0,0034转化为十进制是52,是主版本号,java的版本号从45开始 52对应1.8,接下来就是一些常量池
、方法表集合
等信息 这些字16进制的信息对应为jvm 所认识的字节码指令。
字节码指令集与解析
JVM中的字节码指令集按用途大致分成9类
局部变量压入操作数栈
xload:(其中x 为 i、l、f、d、a)
常量入栈
const、push、ldc
- 算术指令
- 类型转换指令
- 对象的创建与访问指令
- 方法调用与返回指令
1.invokevirtual
指令用于调用对象的实例方法,根据对象的实际类型进行分派(虚方法分派),支持多态,这也是java语言中最常见的方法分派方式。
2.invokerinterface
指令用于调用接口方法,它会在运行时搜索由特定对象所实现的这个接口方法,并找出适合的方法进行调用
3.invokespecial
指令用于调用一些需要特殊处理的实例方法,包括实例初始化方法(构造器)
,私有方法和父类方法,这些方法都是静态类型绑定的,不会在调用时进行动态派发
4.invokestatic
指令用于调用命名类中的类方法(static方法),这是静态绑定的
5.invokedynamic
指令用于调用动态绑定的方法,这是jdk1.7之后新加入的指令,用于在运行时动态解析出调用点限定符所引用的方法,并执行该方法。前面4条调用指令的分派逻辑都固化在java虚拟机内部,而invokedynamic指令的分配逻辑是由用户所设定的引导方法决定的
- 操作数栈管理指令
- 控制转移指令
- 异常处理指令
- 同步控制指令
关于字节码指令集详细:
https://www.cnblogs.com/sjqstart/p/15044517.html
https://blog.csdn.net/mynameisgt/article/details/125052344