栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Java循环在某些运行/ JIT的错误之后变慢?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java循环在某些运行/ JIT的错误之后变慢?

序言:手动编写微基准几乎注定要失败。
有些框架已经解决了常见的基准测试问题。

  1. JIT编译单元是一种方法。将多个基准测试整合到一个方法中会导致无法预测的结果。

  2. JIT严重依赖于执行配置文件,即运行时统计信息。如果某个方法长时间运行第一个方案,JIT将为其优化生成的代码。当该方法突然切换到另一个方案时,不要指望它以相同的速度运行。

  3. JIT可能会跳过优化未执行的代码。它将为该代码留下一个不常见的陷阱。如果遇到陷阱,JVM将取消优化已编译的方法,切换到解释器,然后使用新知识重新编译代码。例如,当您的方法

    run
    在第一个热循环中第一次编译时,JIT尚不知道
    System.out.println
    。一旦执行完成
    println
    ,较早的编译代码很可能会被优化。

  4. 方法越大,为JIT编译器进行优化就越难。例如,似乎没有足够的备用寄存器来容纳所有局部变量。这就是您的情况。

综上所述,您的基准测试似乎通过了以下情形:

  1. 第一个热循环(
    addStatic
    )触发
    run
    方法的编译。执行概要除了
    addStatic
    方法外什么都不知道。
  2. System.out.println
    触发去优化,然后第二个热循环(
    addDynamic
    )导致
    run
    方法重新编译。
  3. 现在执行配置文件仅包含有关的信息
    addDynamic
    ,因此JIT优化了第二个循环,而第一个循环似乎有额外的寄存器溢出:

优化循环:

0x0000000002d01054: add    %rbx,%r140x0000000002d01057: add    $0x1,%rbx          ;*ladd  ; - TestPerformanceOfStaticVsDynamicCalls::addDynamic@2  ; - TestPerformanceOfStaticVsDynamicCalls::run@1050x0000000002d0105b: add    $0x1,%r14          ; OopMap{rbp=Oop off=127}  ;*goto  ; - TestPerformanceOfStaticVsDynamicCalls::run@1160x0000000002d0105f: test   %eax,-0x1c91065(%rip)        # 0x0000000001070000  ;*lload  ; - TestPerformanceOfStaticVsDynamicCalls::run@92  ;   {poll}0x0000000002d01065: cmp    $0x3b9aca00,%rbx0x0000000002d0106c: jl     0x0000000002d01054

循环产生额外的寄存器溢出:

0x0000000002d011d0: mov    0x28(%rsp),%r11  <---- the problem is here0x0000000002d011d5: add    %r10,%r110x0000000002d011d8: add    $0x1,%r100x0000000002d011dc: add    $0x1,%r110x0000000002d011e0: mov    %r11,0x28(%rsp)    ;*ladd  ; - TestPerformanceOfStaticVsDynamicCalls::addStatic@2  ; - TestPerformanceOfStaticVsDynamicCalls::run@330x0000000002d011e5: mov    0x28(%rsp),%r11  <---- the problem is here0x0000000002d011ea: add    $0x1,%r11          ; OopMap{[32]=Oop off=526}  ;*goto  ; - TestPerformanceOfStaticVsDynamicCalls::run@440x0000000002d011ee: test   %eax,-0x1c911f4(%rip)        # 0x0000000001070000  ;*goto  ; - TestPerformanceOfStaticVsDynamicCalls::run@44  ;   {poll}0x0000000002d011f4: cmp    $0x3b9aca00,%r100x0000000002d011fb: jl     0x0000000002d011d0  ;*ifge  ; - TestPerformanceOfStaticVsDynamicCalls::run@25

PS 以下JVM选项对于分析JIT编译很有用:

-XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining -XX:+PrintAssembly -XX:Compileonly=TestPerformanceOfStaticVsDynamicCalls


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/495987.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号