JVM之提前编译器、方法内联、逃逸分析(栈上替换、标量替换、同步消除)(基于《深入理解Java虚拟机》之第11章后端编译与优化)(下)

本文探讨了Java虚拟机中的提前编译技术,包括静态翻译和动态提前编译,以及它们与即时编译器的对比。重点讲解了方法内联、逃逸分析及其优化技术,如栈上分配、标量替换和同步消除,分析了这些优化技术如何提升Java程序的性能和效率。
摘要由CSDN通过智能技术生成

aas 提前编译在Java技术体系中并不是新事物。但是提前编译很快又在Java世界里沉寂了下来,因为当时Java的一个核心优势是平台中立性,其宣传口号是“一次编译,到处运行”,这与平台相关的提前编译在理念上就是直接冲突的
aas 直到在Android的世界里,剑走偏锋使用提前编译的ART(Android Runtime)横空出世。ART一诞生马上就把使用即时编译的Dalvik虚拟机按在地上使劲蹂躏,仅经过Android4.4一个版本的短暂交锋之后,ART就迅速终结了Dalvik的性命[2],把它从Android系统里扫地出门。
asdsadasdasdasdsadasdasdasdsadassdasdsasdsadasdasdsadasdsadassadasdas————《Java虚拟机规范》


提前编译器与即时编译器的对比:
aa
aa提前编译有两条分支:

aasad①、与即时编译器类似:在程序运行之前把程序代码编译成机器码的 静态翻译 工作;

aasad[注]:这是传统的提前编译应用形式,它体现出了直指即时编译的最大弱点:即时编译要占用程序运行时间和运算资源。即使现在先进的即时编译器架构有了分层编译的支持,可以先用快速但低质量的即时编译器为高质量的即时编译器争取出更多编译时间,但是,无论如何,即时编译消耗的时间都是原本可用于程序运行的时间,消耗的运算资源都是原本可用于程序运行的资源。但如果是在程序运行之前进行的静态编译,这些耗时的优化就可以放心大胆地进行了.

aasad②、把原本即时编译器在运行时要做的编译工作提前做好并保存下来,下次运行到这些代码(譬如公共库代码在被同一台机器其他Java进程使用)时直接把它加载进来使用。(已经完全被主流的商用JDK支持)

aasad[注]:
adasasad⒈本质是给即时编译器做缓存加速,去改善Java程序的启动时间,以及需要一段时间预热后才能到达最高性能的问题。这种提前编译被称为动态提前编译(Dynamic AOT)或者索性就大大方方地直接叫即时编译缓存(JIT Caching)。
adasasad⒉实际应用起来并不是那么容易,原因是这种提前编译方式不仅要和目标机器相关,甚至还必须与HotSpot虚拟机的运行时参数绑定。

提前编译的代码输出质量,一定会比即时编译更高吗?
aa
aa提前编译因为没有执行时间和资源限制的压力,能够毫无顾忌地使用 重负载的优化手段,这是一个巨大的优势。但是即时编译器相对提前编译器也有天然优势:(3条)

aa①、性能分析制导优化:(其实就是在编译期无法更准确的收集信息) 在解释器或者客户端编译器运行过程中,会不断收集性能监控信息(譬如某个程序点抽象类通常会是什么实际类型、条件判断通常会走哪条分支、方法调用通常会选择哪个版本、循环通常会进行多少次等),这些数据一般在静态分析时是无法得到的,或者不可能存在确定且唯一的解,最多只能依照一些启发性的条件去进行猜测。但在动态运行时却能看出它们具有非常明显的偏好性。 如果一个条件分支的某一条路径执行特别频繁,而其他路径鲜有问津,那就可以把热的代码集中放到一起,集中优化和分配更好的资源(分支预测、寄存器、缓存等)给它

aa②、激进预测性优化:(其实就是在编译器进行优化要求更加严格,限制更多) 静态优化无论如何都必须保证优化后所有的程序外部可见影响(不仅仅是执行结果)与优化前是等效的,不然优化之后会导致程序报错或者结果不对,即使再快也没有用。而相对于提前编译来说,即时编译的策略就可以不必这样保守,如果性能监控信息能够支持它做出一些正确的可能性很大但无法保证绝对正确的预测判断,就已经可以大胆地按照高概率的假设进行优化,万一真的走到罕见分支上,大不了退回到低级编译器甚至解释器上去执行,并不会出现无法挽救的后果。只要出错概率足够低,这样的优化往往能够大幅度降低目标程序的复杂度,输出运行速度非常高的代码。

aa③、链接时优化:Java语言天生就是动态链接的,一个个Class文件在运行期被加载到虚拟机内存当中,然后在即时编译器里产生优化后的本地代码,这类事情在Java程序员眼里看起来毫无违和之处。但如果类似的场景出现在使用提前编译的语言和程序上,就会出现很明显的边界隔阂,还难以优化。


后端优化技术相关介绍
aa
aaOpenJDK的官方Wiki上,HotSpot虚拟机设计团队列出了一个相对比较全面的、即时编译器中采用的优化技术列表(有的是针对Java语言的,有的是针对运行在JVM上所有语言的优化)。
aa
aa在这里就不放图了,因为毕竟不可能涉及所有的优化,知道这么回事就行了。实际上要实现这些优化确实有不小的难度,但大部分优化技术理解起来都并不困难,要注意即时编译器对这些代码优化变换是建立在代码的中间表示或者是机器码之上的,绝不是直接在Java源码上去做的。
aa
aa我们重点看四个优化方法:
aa
aa最重要的优化技术之一:方法内联。
aa
aa最前沿的优化技术之一:逃逸分析。
aa
aa语言无关的经典优化技术之一:公共子表达式消除。
aa

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值