前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

JVM JIT

作者头像
邹志全
发布2019-10-08 16:27:51
5610
发布2019-10-08 16:27:51
举报
文章被收录于专栏:EffectiveCodingEffectiveCoding

JIT Just In Time,JVM中的一种即时编译技术,目的是为了提升程序的运行效率。

先说一下前提,Java 是一种解释型语言,我们写完Java 代码后,编译器会把Java 编译为对应的字节码,然后由JVM解释执行。但是解释执行,每次执行时都需要对应的去逐条翻译、逐条执行,执行效率比较低下。

后来为了处理 慢 这个问题,JVM 引进了JIT。

JVM的对于JIT使用的运作流程是这样的:

首先我们的Java代码由javac 等编译器 编译为JVM可执行的字节码(ByteCode),然后JVM 会判断这段代码是否为热点代码,如果是那么使用JIT技术,如果不是那么解释执行,最后变成机器码,由操作系统分配然后CPU具体执行。

这里有具体的JVM参数能够调节下述流程:

-Xint全部使用字节码解释执行,这个是最慢的,慢的惊人,通常要比其他方式慢一个数量级左右。

-Xcomp相反,全部被编译成机器码执行,速度是很快的,但是存在一个缺陷,-Xcomp的策略过于简单。

-Xmixed,是一种自适应的方式,有的地方解释执行,有的地方编译执行,具体的策略要依据profile的统计分析来判断。

那具体的JIT操作,就是并非由我们的JVM去解释执行字节码,而是将得到的字节码直接编译成可执行的机器码,之后再调用、执行这一块的代码的时候直接使用机器码就ok了,省去了额外的编译或者解释。

具体的哪一类去解释,这是有具体的热点代码的判断策略来决定的。最常见的类型 比如循环体,高频执行,还有比如一些热点函数。

那既然这样快,为什么不全都去编译执行呢,因为我们程序中有挺大一部分调用频次比较低,并且一次编译的花销要比解释执行大不少,还会有额外的操作。这时去使用JIT就得不偿失了。

除了上述主要的特点外,JVM还有一个很棒的特性叫做自优化,当JIT对一块代码结构非常了解后,会做出具体的优化策略(比如何时从寄存器取值、何时从主存取值)

具体对于我们应该怎么使用或者说利用呢,下面马上介绍

如何选择:

JIT在运行时分为两种模式,客户端&服务端模式(-client、-server),这两种区别还是很大的。-client时会采用一个叫做C1的轻量级编译器,-server时会采用一个叫做C2的重量级编译器。-server 相对于 -client来说编译更彻底,性能也更好。在我们查看电脑的Java会有一个-server或者-client的标示。

这一块需要我们去调配JVM,选择适合我们的编译模式。具体的指定方式:-cient,-server 或是-xx:+TieredCompilation,长时运行就选择server多层编译方式,如果仅仅是临时执行或者短暂执行去选择-client。

如何调优过程:

优化代码缓存相关。

当JVM编译代码时会将汇编指令集保存在代码缓存中,并且这个缓存大小是固定的,当刚开始的时候把这块缓存填满后JVM后续除已缓存的代码外,只能通过解释来执行了。

这其实就是选择-server或者-client 的主要依据了,因为-server方式对热点代码要求会比较高,而-client相对来说就比较简单了对应的会产生大量的热点代码。

除此之外,默认的缓存大小总是少得可怜,我们在运行一些大的、长时项目是时需要适当的调大这一块区域。

-XX:InitialCodeCacheSize=N 修改默认缓存大小

–XX:ReservedCodeCacheSize=N 修改最大缓存大小。

编译阀值相关。

在JVM中存在这么两类计数器,一种是函数的调用次数,另一种是方法中循环被回弹的次数。(这里敲下黑板,回弹低点可不仅仅只有循环体结束处,还有可能是continue)

这两个技术相关的,就是用来判断是否达到标准去编译它。如果有,排队编译。

如果一个函数调用过程中,或者一个循环体执行过程中,虽然马上还要调用或者还会继续下一次循环,这时候也是会触发一个编译操作。将编译的结果替换当前执行的部分,这个操作叫做栈上替换。

具体使用:

-XX:CompileThreshold=Nflag 指定需要的编译次数,-client 默认应该是1500,-server为10000。这东西的修改需要一点点试调。

如果想监控或者观察JVM的编译过程,可以指定-XX:+PrintCompilation,来打印JVM中的编译过程,这一块的信息通过jstat就能看到

jstat -compiler 进称id

编译过程很直观,显然是异步的,具体的数量通过-XX:CICompilerCount=N 调整。

具体的场景,需要具体的调节,没有最好的,只有最合适的。

其实 除了官方的HotSpot JVM,IBM的J9 JVM也是非常值得看一看,对了还有一个叫做classic JVM。

比较着去学习,感觉效果更明显~

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.10.03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档