关于 Java 中 JIT 的问题 - V2EX
cc959798
V2EX    Java

关于 Java 中 JIT 的问题

  •  1
     
  •   cc959798 Aug 14, 2018 3374 views
    This topic created in 2828 days ago, the information mentioned may be changed or developed.

    小白咨询大家一个问题,轻喷呀

    1.JIT 会把部分热点代码直接编译成本机能够执行的机器码,那为什么不把所有的代码都直接在运行的时候编译成机器码呢?这样整个程序会更快些,由于内存吗?现在的机器内存都不太稀缺,对于服务端程序来说内存应该是可承受的吧 2.JIT 中把部分程序编译成机器码,部分不是,直接解释执行,请问两者之间有什么具体的区别,就算是解释执行的话机器应该也只是执行机器码吗?

    真心求教

    14 replies    2018-08-15 12:13:07 +08:00
    wwqgtxx
        1
    wwqgtxx  
       Aug 14, 2018 via iPhone
    全部编译那就是 aot 了,主要还是编译消耗 cpu 资源,你看看 android5.0 那慢到窒息的 app 安装速度,到 android6.0 就改回 jit 了
    另外一方面是 jit 可以分层优化,特别是可以边运行边优化,在代码运行到一定次数的时候,能动态把不必要的循环,递归都优化掉

    解析执行的意思是一行一行的翻译执行,编译成机器码就是不在需要翻译了,当然最后执行的都是机器码
    zjp
        2
    zjp  
       Aug 14, 2018 via Android
    得看场景,JVM 分客户端模式和服务器模式。一般客户端在意启动速度,运行时间不长。可以假设一种极端情况,解析执行的执行完了,编译还没完成。
    ekoeko
        3
    ekoeko  
       Aug 14, 2018
    @wwqgtxx 请问,服务端更新应该不频繁,启动慢点无所谓吧,是不是可以把服务端的程序全部编译好再执行, 后面运行的效率会更高吧?这样会不会更好?
    loqixh
        4
    loqixh  
       Aug 14, 2018
    策略不同而已 .net 就是方法第一次执行时编译成机器码, 不存在解释执行
    aidoudou
        5
    aidoudou  
       Aug 14, 2018
    个人理解:一般是采用并存的分层编译。热点代码要根据运行情况的性能监控来通过 JIT 优化;非热点代码,解释执行可以节约内存,并且没有通过 JIT 的必要。这其中应该有一个大致的平衡点(所以需要监控热点代码),单方面的全部 JIT 或者全部解释执行应该都不可取。
    lovedebug
        6
    lovedebug  
       Aug 14, 2018 via Android
    1. 很多代码只执行一次或很少执行,热编译反而代价大
    2.JIT 要考虑到多线程同步问题和内存模型
    looplj
        7
    looplj  
       Aug 14, 2018 via Android
    JIT 比较激进。如果发生 deoptimization 代价挺大的,所以不会全部 JIT。
    lurenw
        8
    lurenw  
       Aug 14, 2018
    1. 在运行前编译叫做 AOT ( ahead-of-time ), 在运行前编译的好处是节省整个运行环节的时间,毕竟都是机器码了。缺点就是 AOT 不能根据运行时的状态做对应的优化,所以可能会做许多多余的优化
    2. JIT 有个 PGO,在程序运行的时候采集信息(比如热点代码),然后可以做针对性的优化
    3. 解释执行和编译执行到最后都是机器码。比如有些代码只跑一次,此时就没啥必要编译之后再跑,直接分析语法,最后转成机器码会快很多。
    momocraft
        9
    momocraft  
       Aug 14, 2018
    JIT 编译不一定只发生一次 ,也不一定启动就能做(一些优化需要运行时信息)
    luozic
        10
    luozic  
       Aug 14, 2018 via iPhone
    可以手动指定编译方式。并且 hotspot 是 JiT 的一种方式,并不是所有的 JIT 使用这种方式实现
    kaneg
        11
    kaneg  
       Aug 14, 2018 via iPhone
    很多代码在运行时才知道会不会执行到,举个极端的例子:classpath 有上百个 jar,但在 main 方法里只打印了 hello world 就结束了,这种情况下提前优化就没有意义。
    cc128
        12
    cc128  
       Aug 14, 2018 via Android
    编译的机器码体积要大很多。全部编译占用内存是一定的。jit 也会占用很多系统资源。而且 jit 是有一个阀值的。这里说的是 android,dalvok 和 art 的 jit 又不太一样。之前 android6.0 里 jit cache 是限制在 2m,6.0 没 release,7.0 又改了很多。结合了 aot+jit,并且把 jit 延迟到用户充电这种情况下。并且编译结果写入到一个文件。所以如果全部编译时间和空间都是一个大问题。还不如 aot。Aot 的话机器码是在磁盘上,是映射到内存。

    编译出来的机器码是包含了虚拟机相关操作的。比如调用一个方法,并不是直接编译成 blx 或 call 指令。解释执行等于是查字典。每一条字节码指令对应一段虚拟机中行的代码。android 上是 switch case,goto 这种样子的。比如你调用函数,就会执行 INVOKE _VIRTUAL 的指令。

    解释执行和机器码之间相互调用是通过汇编和 c 关联起来的。还涉及 manager stack 数据和 native stwck 数据的交换转移。

    总的说细节还是很多。。。
    LukeChien
        13
    LukeChien  
       Aug 15, 2018 via Android
    可能是技术还不成熟,Java9 已经可以完全 JIT 编译成原生代码了
    wwqgtxx
        14
    wwqgtxx  
       Aug 15, 2018
    @LukeChien 我记得并不可以完全编译,AOT 仅限于标准库
    About     Help     Advertise     Blog     API     FAQ     Solana     3090 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 81ms UTC 15:08 PVG 23:08 LAX 08:08 JFK 11:08
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86