上面文章在介绍Java的内存模型的时候,提到过因为编译器的优化会致使重排序的问题,其中一个比较重要的点地方就是关于JIT编译器的功能。JIT的英文单词是Just In Time翻译成中文就是及时,刚好的意思,意在说明JIT编译器优化java的class文件里面的byte code是拿捏的恰到好处。java
JIT编译器是JRE里面的一个为了在运行时提高Java程序性能的一个重要组件,咱们知道Java代码一大优点就是在于一次编写,处处运行的特色。Java程序一般在编译后是一大堆class文件,也就是咱们所说的字节码,而后经过JVM来解释执行这些与平台无关的字节码,从而屏蔽了操做系统的差别,作到了跨平台的特色。但jvm在在运行时候执行class文件的字节码的时候性能并无执行跟操做系统直接有关的机器指令性能来的快,正是由于这个缘由,才出现JIT编译器,目的就是为了提升执行效率。缓存
到这里,咱们再总结下JIT编译器的定义:数据结构
==在Java程序运行时把一些class文件的字节码给转变成操做系统本地的指令码,从而提高程序性能。==多线程
以下图: app
在上面的图咱们可以看到,咱们的java源文件先在编译时被转成class字节码文件,而后在运行时会在当一个方法第一次调用时会被JIT再次编译优化转成native machine code也就是上面说的操做系统级别的指令。jvm
这里面你们注意到仅仅当方法第一次调用时才会进行JIT优化,那么有个问题是既然JIT编译器优化运行时执行性能,为啥不把全部的方法都优化一次呢,而非得时用到的时候才优化呢? 这正是just in time写照。 当JVM启动时候,其实是会加载数千个方法的,理论上把全部方法都提早经过JIT转换一下是会提高更多运行性能,但实际状况是JIT编译优化是须要耗费必定的cpu和内存资源(用来缓存指令),这也意味着若是直接优化全部方法,有可能致使jvm启动的很是慢,即便它能在运行时带来的必定的性能提高。性能
此外,JIT在运行时作编译优化是须要从新理解字节码的语义的,为了分析方法,它的字节码会被转成一种叫作trace tree的数据结构,而后根据方法的trace tree来作相关分析和优化,最终字节码会被转成本地的机器码。固然JIT会使用多线程来编译task,从而使java应用程序也就是jvm启动的更快。到这里相信看了我上篇文章的同窗们,就会明白重排序的问题。学习
你看到的代码顺序,未必是其执行顺序优化
这其实就是由于JIT在底层编译优化的时候为了提高编译的性能,是会把字节码放到多个线程里面的执行的,固然这里面必须保证单线程JIT优化不影响最终结果的逻辑,这就是后面会提到的关于 happend-before的约束。操作系统
最后咱们来看下JIT编译优化的包括几个方面:
(1)代码内联 (合并trace tree里面小的方法)
(2)本地优化(本地分析和优化代码的一小部分,一般使用静态编译器)
(3)控制流优化(从新排列控制流的代码路径进行优化)
(4)全局优化(对整个方法进行优化)
(5)本地字节码生成(根据不一样的操做系统,生成对应优化的本地机器码)
总结:
本篇文章主要介绍了Java里面JIT编译器相关的内容,经过学习咱们应该认识到Java编译的字节码方法并不必定是直接就运行的,更多时候是会以 “延迟加载” 形式经过JIT优化,这样把Java字节码转成本地的机器码能更多的提高程序运行效率。