JVM5:JIT即时编译

JIT Compiler(即时编译器)全称为Just In Time,为JVM的一部分。众所周知,JIT技术可以提高Java代码的运行速度。本文将将通过以下问题来了解分析JIT:

  • 什么是JIT?
  • JIT如何有针对性地优化代码
  • 如何优化JIT

1. 什么是JIT?

在解释JIT是什么之前,让我们一起了解以下Java代码从源码到被机器执行的流程。

Java在被JVM执行前需要被编译,即将我们写在.java文件中的源代码转换成.class文件中的字节码。通常在IntelliJ、Eclipse等IDE中已经集成了这类编译器,所以无需我们手动进行编译。如果要手动编译Java源码,需要用javac命令进行编译,例如javac Test.java。 这里的编译为运行前编译,代码完成运行前编译后就可以直接交付JVM运行了。Java的字节码是平台无关的,因为JVM会将相对应的字节码解释为可执行的汇编码。解释在JVM启动时开始,是字节码执行最慢的形式。这里Java就相当于和Python一样的解释性语言,当然Java并非解释性语言,而是“混合模式”语言,同时运用解释执行和编译执行两种方式。Java如何将字节码一一对应到机器码则不在本文的讨论范围内。

JVM混合模式

为什么解释执行慢?因为JVM每次运行相应的字节码时,都要将字节码解释成对应的机器码。其中有很多的重复性工作,例如一个将被运行10000次的循环将被解释10000次。为了提高运行效率,JIT顺势登场。

JIT是JVM中的一个自适应优化器,会有针对性地优化被JVM证明为代码性能关键的方法。JIT的优化则是将该方法的代码编译保存,随后JVM运行该方法时就无需再对方法进行解释转换为汇编码。在了解了什么是JIT后,下面我们一起看看JIT是如何工作的。

2. JIT如何有针对性地优化代码

既然JIT会对代码中性能关键的方法进行优化,那么JIT是如何识别这些方法的呢?为了确定代码中的性能关键方法,JVM会在代码解释运行时监控关注以下指标:

  • 方法进入计数器:为每个方法分配一个调用计数器。
  • 循环分支计数器:为每个已执行的循环分配一个计数器。

如果一个方法的调用次数超过JVM设定的编译临界值,则该方法被认为是代码中的性能关键方法;同理,假如一个循环执行次数超过JVM设定的编译临界值,则该循环也被认为是性能关键的。如第一部分指出,JIT对这些性能关键方法的优化就是将代码编译保存,并在下一次调用时执行。这里需要注意的是:当一个循环被编译后,再进入循环执行的就是编译过后的代码,而非将字节码翻译成机器码。这里的优化被称作栈上替换(OSR: On Stack Replacement),因为JVM是在栈上替换编译代码的。

在了解了JIT如何确定性能关键方法后,我们该如何根据JIT的特性对它进行相应的优化,使之更好地适应我们的代码呢?

3. 如何优化JIT

3.1 选择编译临界值

从第二部分我们可以知道,JIT有编译的临界值。编译临界值是可以选择的,比如最简单的就是选择不同的JVM模式。Java为JIT提供了两种编译模式,分别是clientserver模式。二者的区别是编译的临界值不同:

  • Client模式下,JIT的编译临界值比较低,为1500。
  • Server模式下,JIT的编译临界值比较高,为10000。

根据不同应用的需要,我们可以选择合适的模式。我们可以通过java --version命令行来找到我们用的是什么模式,通常JDK提供的是混合模式。以防需要,这里有一个修改模式的方法,仅供参考:
StackOverflow: Change default java vm to client

注意:我按照这个方式尝试了,但是没有成功。jvm.cfg文件对用户只有可读权限,我用sudo chmod命令修改权限并修改了模式,但是未能改变编译模式。

3.2 JIT的分层编译

我们常用的OpenJDK HotSpot VM就使用了分层编译。我们可以通过-XX:+TieredCompilation命令行来启用分成编译。从InfoQ的一篇文章中找到了一段关于分层编译的描述:

With the introduction of tiered compilation, OpenJDK HotSpot VM users can benefit from improved startup times with the server compiler.
Tiered compilation has five tiers of optimization. It starts in tier-0, the interpreter tier, where instrumentation provides information on the performance critical methods. Soon enough the tier 1 level, the simple C1 (client) compiler, optimizes the code. At tier 1, there is no profiling information. Next comes tier 2, where only a few methods are compiled (again by the client compiler). At tier 2, for those few methods, profiling information is gathered for entry-counters and loop-back branches. Tier 3 would then see all the methods getting compiled by the client compiler with full profiling information, and finally tier 4 would avail itself of C2, the server compiler.

3.3 分层编译与代码缓存

分层编译带来的另一个好处是我们可以针对每一层进行编译临界值的设定,例如

-XX:Tier3MinInvocationThreshold,
-XX:Tier3CompileThreshold, 
-XX:Tier3BackEdgeThreshold

第三层编译的最低阈值为100,这样,大量的方法都将被编译。大量方法被编译将产生新的问题。因为JVM会将编译后的代码存放在代码缓存中,编译越多的代码就需要越多的缓存空间。在OpenJDK中默认可用的分层编译代码缓存大小为240MB,而用于不分层的代码缓存大小只有48MB。JVM会在代码缓存满时发出警告,我们也可以通过-XX:ReservedCodeCacheSize来设定我们需要的代码缓存的大小。

3.4 获取编译信息

为了更好地了解编译情况,OpenJDK HotSpot VM提供了-XX:+PrintCompilation命令来告诉用户代码的编译情况。

4. 参考:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容