JIT
JIT,又是一块带肉的骨头;just-in-time compilation,运行时编译,吭哧吭哧写了半天的bug不能到最后还让人来做吧?“侬脑子瓦特了”——当然是交给机器做,javac把java源文件翻译成class文件(字节码组成),jvm加载这些文件逐条取出字节码并执行,这就是解释执行了!当然还可以重新编译优化字节码以生成机器码,CPU直接执行,这样效率更高,这里有java如此受欢迎的原因,这里点破不说破,然后怎么让机器去执行呐?当然是告诉它了:要有源代码或者字节码到机器码的转换过程,这样到最后阶段用他们机器的语言和他们对上话,在废话中我们说到了java的分离编译和动态类加载,这……又抽象了:运行时编译,在程序执行过程中(也就是运行期)源代码或字节码转换成机器码,然后执行,这样是不是需要不断分析正在执行的代码,这个编译或重新编译的过程开销还是不容小觑的,这怎么办?俗话说:哪里有困难那里有方法,针对这种情况jit编译还是用心地做了优化,容许自适应优化:重编译和特定于微架构的加速
简单来说:JIT就是申请一块可读写可执行的内存,把编译的java代码翻译成机器码,写入那块内存,需要调用时转向调用这块内存(模板解释器,有没有),这是有点过于简单哈~
字节码不是某种计算机的专属机器代码,它是大家的,可在计算机体系结构间游走,在虚拟机上解释字节码成机器码或JIT读取动态编译成机器码、缓存结果便于复用,机器码运行,所以总的来说,优点如下:
- 编译可优化目标CPU和操作系统模型:检测到支持什么便可进行选择,静态编译器需为每个预取的平台编译二进制文件或文件中含多个版本的部分代码
- 收集程序所在环境运行情况的统计信息,可重新排列和编译来获得最佳性能,实时的知己知彼
- 全局代码优化:使用缓存什么的减少工作量
当然怎么一丁点缺点都没有?加载和编译字节码它不需要时间吗?这个时间是程序初始化中延迟的元凶!专业一点叫做“启动时间延迟”或“预热时间”,其实也不是很专业O(∩_∩)O,so JIT优化越多、生成的代码越好,这个延迟时间可能越长,优胜劣汰,它必须去做权衡
针对这些HotSpoot选择了将解释和JIT编译结合,程序代码最初被解释,JVM监视哪些字节码经常被执行标记为“热点”将其转为机器代码方便在硬件上直接执行;二八定律不知道大家知不知道,感觉哪里都有他,大部分情况程序花费大量时间其实只是为了执行一小部分代码,所以编译前收集执行统计信息,可以更好的优化,这在之前也提到过一二,当然具体情况具体分析,Sun的java虚拟机这方面为我们做了很好的示例:针对常见情况分了客户机和服务器两种模式
- 客户机(客户段)执行最小程序的编译和优化,来减少启动时间
- 服务器模式:执行大量编译和优化,必然牺牲启动时间来提高程序运行时性能
其他的java编译器也是很努力的:
- 特定方法度量方法的执行次数,结合方法字节码大小来决定合适编译
- 组合使用执行次数和检测循环 做权衡做事情
- 等
参考:
https://www.zhihu.com/question/21093419 thanks lcksuper for the picture
https://zh.wikipedia.org/wiki/%E5%8D%B3%E6%99%82%E7%B7%A8%E8%AD%AF wiki
您可能是从对象一定分配在堆上吗?来的,传送门