深入理解jvm系列是对郑雨迪老师在极客时间的课程深入拆解java虚拟机的笔记,想要查看完整课程的可以点击前面的链接,需要购买的同学可以扫面下方的二维码
大家都知道java代码都是运行在java虚拟机上的,那么到底代码怎么样执行的呢?下面两个图帮大家有个总体的认识
java的代码需要编译成class文件,class文件保存的是java的操作码(opcode),操作码又被称为java字节码,因为每条java的操作码都是一个字节。java的操作码可以被反汇编成人类能读懂的指令:
# 最左列是偏移;中间列是给虚拟机读的机器码;最右列是给人读的代码
0x00: b2 00 02 getstatic java.lang.System.out
0x03: 12 03 ldc "Hello, World!"
0x05: b6 00 04 invokevirtual java.io.PrintStream.println
0x08: b1 return
这就是class文件的存储内容,操作码不能被硬件机器直接执行,需要翻译成机器指令才能正常运行
java操作码执行过程有两个:
- 解释执行,当执行java方法时,逐条翻译执行
- 即时编译器:java方法高频访问,被翻译成机器码,直接执行。
效率
我们会反省,java字节码执行的效率是不是会太差,其实jvm为了修补解释执行的性能缺陷,引入了即时编译器,可以把高频的java方法直接编译成机器码,直接访问唯一实现的方法,避免虚方法调用带来的性能消耗,这样就可以媲美甚至超过C++的执行速度。
即时编译器有C1/C2/Graal ,C1是client编译器,当jvm处理客户端GUI的性能优化
C2是server编译器对服务器的高吞吐量有优化
Graal 是java10 引入的,没讲到