代码编译的过程就是把class字节码编译成机器语言,使机器能够直接运行的过程。
JIT 编译器在运行程序时有两种编译模式可以选择,并且其会在运行时决定使用哪一种以达到最优性能。这两种编译模式的命名源自于命令行参数(eg: -client 或者 -server)。JVM Server 模式与 client 模式启动,最主要的差别在于:-server 模式启动时,速度较慢,但是一旦运行起来后,性能将会有很大的提升。原因是:当虚拟机运行在-client 模式的时候,使用的是一个代号为 C1 的轻量级编译器,而-server 模式启动的虚拟机采用相对重量级代号为 C2 的编译器。C2 比 C1 编译器编译的相对彻底,服务起来之后,性能更高。默认就是server模式
zhangshldeMacBook-Pro:~ zhangshl$ java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
zhangshldeMacBook-Pro:~ zhangshl$
普通情况下,代码都是有解释器编译然后运行,标准编译是被-XX:CompileThreshold=Nflag 的值所触发,Client 编译器模式下,N 默认的值 1500,而 Server 编译器模式下,N 默认的值则是 10000,如果代码重复执行了10000次,则认为是热点代码,则有JIT编译并缓存起来,下次不必再进行代码编译,可直接利用编译好的代码执行。
可以通过 –XX:ReservedCodeCacheSize=Nflag(N 就是之前提到的默认大小)来最大化代码缓存大小。代码缓存的管理类似于 JVM 中的内存管理:有一个初始大小(用-XX:InitialCodeCacheSize=N 来声明)。代码缓存的大小从初始大小开始,随着缓存被填满而逐渐扩大。代码缓存的初始大小是基于芯片架构(例如 Intel 系列机器,client 编译器模式下代码缓存大小起始于 160KB,server 编译器模式下代码缓存大小则起始于 2496KB)以及使用的编译器的。重定义代码缓存的大小并不会真正影响性能,所以设置 ReservedCodeCacheSize 的大小一般是必要的。
调优:
阈值可以调整,10000次可以调整为别的值如8000次
缓存大小可以调整