程序编译与代码优化:晚期(运行期)优化

前言:写这篇文章的目的在于梳理清楚程序运行期jvm做了哪些优化事情,为程序带来了哪些好处!

待解答疑问:
1、运行期的优化动作为什么不放到编译期进行?

那么此文将从五个方面来说明运行期编译优化的过程:

  • why: 为什么要进行运行期优化?
  • what: 优化什么?
  • who: 谁来优化?
  • when: 何时优化?
  • how:怎样优化?
why:为什么要进行运行期优化?
运行期将中间格式的.class文件直接编译成硬件相关的机器码,省略了每次运行时转换的时间,进一步压榨性能。
why:优化什么?
核心是将.class文件转换生成机器码。同时在编译成机器码的过程中会对程序代码做优化,比如逻辑简化(简化后的代码执行结果不变,但对堆、栈等寄存器的访问次数减少)、甚至一些激进的优化手段(这些优化并不一定总是成立,只有在满足某些条件的时候才能提高性能)。
who:谁来优化?
即时类编译器,如:c1编译器
何时优化?
程序运行过程中满足相应条件时触发编译。例如:通过热点代码记录,一段代码被执行了10w次就编译成机器码。后续就采用机器码直接执行!
怎样优化?
除将.class编译成机器码外,其它代码层面的优化方式主要包括(仅例子说明):
  • 方法内联:将被调用的方法代码按照一定规则复制揉合到调用的点中。减少调用的消耗;
  • 数组越界检查:每次访问数组元素,都要判断是否越界。如果jvm在运行过程中已经记录出程序越界的概率极低。就可以采用激进的优化手段,放弃每次访问时的越界判断。改成直接访问,若真的越界时异常捕获。通过概率的分析提高运行效率!
    注:此点涉及内核态线程切换的效率问题,待研究;
  • 逃逸分析:代码中的同步逻辑(包括应用程序自身设置的同步,或者jre中api自带的)极其消耗性能。若jvm能分析出一段同步的逻辑,在任何情况下都不可能被其它线程访问(也就是不存在资源竞争的情况),就可以擦除同步修饰符以提高运行效率。
运行期的优化动作为什么不放到编译期进行?
  • 运行期可以统一给不同语言提供优化。jvm上支持运行任何符合.class文件格式规范的内容,而不关心程序的源语言是什么,比如是java还是jRuby,或其它。如果优化放在编译期,也就是java、jRuby等的编译器各自都要实现各自语言优化逻辑。而放在运行期则很好的避免了重复。这也是为什么jvm团队几乎把所有有利于性能提升的优化都放在运行期的主要原因;
  • 一些激进但有效的优化手段需要基于运行的数据。比如上面提到的数组越界检查。如果程序越界的概率较高(在程序运行之前是无法知晓越界概率高低的),采用此种优化就会导致频繁的异常,线程反复切换反而降低了运行效率;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值