一:两种解释器
JAVA字节码解释器:
java字节码===》c++代码==》硬编码。
首先.java文件编译成字节码,遍历每行的字节码指令,因为每个字节码指令的含义都是固定的所以可以根据每行字节码指令来转成c++代码调用,最后转成硬编码(机器码)来执行。
模板解释器:
由java字节码==》硬编码。可以从java字节码直接到硬编码。
模板解释器底层实现流程:
1)申请一块内存:可读可写可执行
2)将处理new字节码的硬编码(举个例子)拿过来,可以通过解析文件得到
3)将处理new字节码的硬编码写入申请的内存
4)申请一个函数指针,用这个函数指针执向这块内存
5)调用的时候,直接通过这个函数指针调用就可以了。
Mac中是无法使用JIT的!因为Mac无法申请一块可读可写可执行的内存块
二:三种运行模式-Xint 纯字节码解释器
-Xcomp 纯模板解释器
-Xmixed 字节码解释器+模板解释器
默认是mixed,可以通过java -version查看
混合模式
纯字节码解释器
纯模板解释器:
三:三种运行模式的性能
1:-Xint 纯字节码解释器, 解释一行执行一行,其实属于解释执行了。如果代码多的话肯定效率不会太高。
2:-Xcomp 纯模板解释器,需要把.class编译成硬编码之后再执行,如果程序很大,启动时间耗时可能会较久。
3:-Xmixed 字节码解释器+模板解释器,所以现在都是混合模式的编译。刚启动的时候采用字节码解释器,这样只要解析执行启动相关的代码即可,等到程序运行一段时间之后,即时编译器收集到的代码越来越多就可以使用模板解释器提高运行效率。
2,3那个性能比较高,主要看程序的规模了。
四:模板解释器使用的硬编码谁来编译呢?编译后又是放在哪里呢?即时编译器:属于JIT技术。
1)C1即时编译器。
c1编译器是client模式下的即时编译器。现在64bit机都是server模式了
(1)触发条件比C2宽松,需要收集的数据较少。
(2)编译的优化比较浅比如:基本运算在编译的时候运算掉了或这final 修饰的字符串的优化。
(3)c1编译器编译生成的代码执行效率比c2低些。
就算对其进行调优,性能的提升曲线也很平缓。
2)C2编译器
c2编译器是server模式下的即时编译器。
(1)触发的条件比较严格,一般来说,程序运行一段时间以后触发。
(2)优化的比较深。比如编译的时候判断操作是否设计到堆栈,如果没有的话直接优化掉了。
(3)编译生成的代码执行效率比c1更高。
3) 混合编译
jdk6以前是没有混合编译的,后来根据两种编译器的使用场景组合起来使用进一步提升性能
程序运行初期触发c1编译器,程序运行一段之后触发c2编译器。
这里说明一点:
字节码解释器是解释执行的,和即时编译器无关。
模板解释器执行的硬编码就是即时编译器编译的。
即时编译触发的条件!
硬编码在jvm中称为热点代码。
触发即时编译的最小单位不是一个函数,而是一个代码块(for,while等)
client模式下,默认值 1500。即一段代码执行1500次会触发即时编译。
server模式下,默认值是10000。即一段代码执行10000次会触发即时编译。
热度衰减:
有一段代码执行了7000次,还有3001次触发即时编译,但是在一定时间内,这段代码没有被调用,这个次数会以两倍速递减变成3500,这时候就需要再执行6501次才会触发即时编译。这种就叫热度衰减。
补充知识点!!!!!!!
热机切冷故障。
热机:就是已经运行了一段时间的机器。
冷机:就是刚运行的机器。
问题:
当给已经运行了一段时间的热机集群中增加一个节点冷机的时候,冷机起到负载均衡的作用,但是会出现冷机一上线就会挂掉。