JVM:基本原理之java代码的运行

【关于作者】

关于作者,我目前蚂蚁金服搬砖任职,在营销投放领域工作了多年,目前在专注于内存数据库相关的应用学习,如果你有任何技术交流或大厂内推及面试咨询,都可以从我的个人博客(https://0522-isniceday.top/)联系上我~

1.为什么Java要在虚拟机中运行

java是一门高级语言,语法非常复杂,抽象程度非常高,因此直接在硬件上运行并不现实,因此再运行之前,我们对其进行转换。转换的思路就是将代码编译为虚拟机能够识别的指令序列(java字节码,之所以这样命名是由于java字节码指令的操作码被固定为一个字节)

java虚拟机:虚拟机可以由硬件实现也可以由软件(jdk)实现,目前windows和linux大部分采取的软件实现

其中虚拟机带来的好处如下:

  • 一次编写,到处运行

    程序被转化为字节码,便可以在不同环境的虚拟机中运行

  • 自动内存管理和垃圾回收

    虚拟机带来了托管环境,托管环境能够处理代码中运行时容易出错的部分,包括内存管理和垃圾回收

2.Java虚拟机如何运行Java字节码

下面所述都是以标准JDK的HotSpot为例

虚拟机视角

将编译而成的字节码文件加载到虚拟机中,加载后的类会放置在运行时的方法区(Method Area)中,实际运行中,虚拟机会执行方法区内的代码

虚拟机将栈细分为面向Java方法的Java方法栈,面向本地方法的本地方法(用C++写的native方法,在jdk源码中有大量使用)栈,以及存放各个线程执行位置的PC寄存器

img

由上图我们可以看到还有线程私有的方法区,那么这里的方法区是拿来干什么的呢?

在运行过程中,每当调用一个方法,会给当前线程的java方法栈中生成一个栈帧,用于存放局部变量和字节码的操作数。栈帧大小是提前计算好了,不需要分配连续的空间。退出当前执行的方法时,不管是正常返回还是异常返回,Java虚拟机都会执行当前线程的该方法的弹栈操作

硬件视角

Java字节码无法直接执行,因此虚拟机需要将字节码翻译为机器码

对于Hot Spot而言,上述翻译过程,有两个办法:

  • 解释执行:逐条将字节码翻译为机器码并执行,翻译和执行是同步的,所以说无需等待编译
  • 即时编译(Just-In-Time compilation,JIT):将一个方法中包含的所有字节码编译成机器码再执行,先翻译再执行,能获得到运行时的信息,因此运行效率有时候会优于C++

前者的优势在于无需等待编译,后者的优势在于实际运行速度更快。Hot Spot默认采用混合模式,综合了解释执行和即时编译两者的优点。它会先解释执行字节码,而后将其中反复执行的热点代码,以方法为单位进行即时编译

1

3.Java虚拟机的运行效率

Hot Spot对于大部分不常用的代码采取解释执行的方式运行,对于常用的代码将其编译成字节码,以达到理想的运行速度

Hot Spot内置两个即时编译器:C1、C2

  • C1:又叫做Client编译器,面对的是对启动性能有要求的客户端GUI程序,编译时间较短
  • C2:又叫做Server编译器,面对的是对峰值性能有要求的服务端程序,优化手段比较复杂,编译时间较长。但生成代码的执行效率高

Java7开始采用分层编译:

  • 热点方法首先会被C1编译,热点方法中的热点会进一步被C2编译
  • 为了不干扰正常应用的运行,即时编译会被放在额外的编译线程运行,HotSpot 会根据 CPU 的数量设置编译线程的数目,并且按 1:2 的比例配置给 C1 及 C2 编译器
  • 资源充足的情况下,解释执行和即时编译同时进行,编译完成的机器码会在下次调用时启用,替换原本的解释执行
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈哈哈张大侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值