让java性能提升的JIT深度解析

在从事Java开始的一段时间,那时候经常可以听到什么C++的瞧不起写Java的,在一些群里也经常看到二个派的人经常互怼。Java能够这么流行与它的跨平台,语言无关性是分不开的,不管你是用Java,python还是Go,只要变成对应的标准字节码文件,那么JVM都是可以识别并执行的,但是那时候的Java之所以被C++吐槽主要还是因为Java  ,为什么这么说呢。

我们写的程序虽然能被JVM识别,但是不能被机器识别,程序要运行起来,还是得让机器能够识别你的程序,所以JVM还需要一个 解释器 ,这个解释器就是将你的程序转换成机器能识别的指令,然后执行,如下图

让java性能提升的JIT深度解析_第1张图片

对于一个长期运行的Java进程来说,每次执行都要经过 解释器 将程序翻译成机器指令去执行,那么这个效率就不是很好,这也是为什么Java被吐槽  的缘故,所以为了解决这个问题,才出现了 JIT 。

对于一些热点代码(经常被执行的,for循环)的一些代码,在运行时,JVM会将这些代码编译成机器可以执行的机器码,并缓存起来,这样下次执行这些代码的时候,就不需要再经过 解释器 去编译了,机器可以直接运行这段程序,提高性能,这个就被称为 即时编译器 ,简称 JIT编译器

JIT的种类

让java性能提升的JIT深度解析_第2张图片

在JDK1.8中HotSpot虚拟机中,内置了二个JIT,分别为C1编译器和C2编译器

C1编译器:是一个简单快速的编译器,主要关注点在于局部性的优化,适用于执行时间较短或者对启动性能有要求的程序,C1编译器几乎不会对代码进行优化

C2编译器:是为长期运行的服务器端应用程序做性能调优的编译器,适用于执行时间较长或对峰值性能有要求的程序,根据各自的适配性,这种即时编译也被称为Server Compiler,但是由于C2代码超级复杂,无人维护,所以才会开发Java编写的Graal编译器代替C2

热点代码

JIT会将一些热点代码编译成机器能够识别的机器码然后缓存起来,比如一些经常被调用的代码,还有for循环中的代码,那么JIT如何识别出哪些是热点代码呢??

为什么说是一些热点代码缓存起来,而不是全部呢?因为缓存是需要空间存储的,可以通过以下命令查看该缓存的大小

java -XX:+PrintFlagsFinal –version
复制代码

你可能感兴趣的:(Java,java,jvm,开发语言)