JAVA为什么在出现JIT技术之后,没有全面转为编译执行?

JAVA是解释执行语言,还是编译执行语言?

在最早的时候(JIT诞生前),如果问一个JAVA开发者,JAVA是解释执行的语言还是编译执行的语言,相信100%的人都会回答“解释执行”。
但是到了今天,再说JAVA是解释执行的就不正确了
为什么呢?跟JIT有关

什么是JIT(Just In Time)

通常情况下,JVM会加载.class文件,并在程序执行时,逐行读取、解释、执行
JIT是JVM的即时编译器,能够让JVM把代码编译成机器码,这样在执行这一段代码时,可以直接执行机器码,相对于解释一行执行一行的“解释执行”而言,效率大幅度提高。在执行这一段代码的时候,JAVA就是“编译执行”的模式

目前主流的HotSpot虚拟机默认是解释执行+编译执行共存的模式。JVM会自动将频繁执行的代码片段编译成机器码,这样就避免了频繁解释相同的代码带来的性能浪费

到这里问题就来了,既然编译执行速度比解释执行快很多,为什么不干脆把所有字节码都编译成机器码呢?接下来我们就来探讨这个问题

为什么不全部代码都编译成机器码?

如果我们要把java代码编译成机器码,可以在两个阶段进行,分别是 源码编译时和JVM加载.class文件字节码时,但是他们都各自有不同的问题

编译源码时,直接编码成机器码

首先,技术上是完全可行的
但是,JAVA很重要的一项特性,就是跨平台,号称“一次书写,随处运行”。如果编译源码时直接编译成机器码,那么就失去了跨平台的特性了,因为不同CPU、不同系统内核可执行的机器码是不一样的。所以这个方案行不通

JVM加载CLASS文件时,直接用JIT技术全部编译成机器码

技术上依然是可行的
但是将代码编译成机器码是有代价的,那就是
编译耗时将会导致JAVA程序启动时间大幅度延长
以及
编译后的机器码需要占用大量内存
对于启动时间延长的问题,我们可能会说,在服务器上,启动时间变长并非完全不能接受,毕竟谁的服务会经常重启呢

没错,但是这不足以让JVM的开发者们完全把代码都编译成机器码。但是,HotSpot JVM在server模式运行的时,会更容易倾向于把代码编译成机器码,表现在对“热点代码”的判断严格程度比client模式要宽松,但是依然没有将全部代码都编译成机器码

第二点,对于内存资源的占用就比较难办了,近些年来,内存资源变得不再像以前一样昂贵和紧缺,但是在过去很长一段时间里,内存都不是我们可以随意挥霍的资源。结合成本和收益来考量,主流的JVM还是没有把全部代码都编译成机器码

但是oracle JDK9 提供了实验性质的AOT((Ahead-of-Time Compilation)功能,支持把class文件直接编译成机器码文件,这样就省去了JIT的工作,启动时,直接使用编译后的文件启动即可

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值