深入理解JVM原理5—哪些代码需要编译?

1 什么是热点代码

在程序中哪些代码会被编译呢?
程序中的代码只有是热点代码时,才会编译为本地代码,那么什么是热点代码呢?

运行过程中会被即时编译器编译的“热点代码”有两类:

  1. 被多次调用的方法。
  2. 被多次执行的循环体。

这两种情况,编译器都是以整个方法作为编译对象。这种编译方法因为编译发生在方法执行过程之中,因此形象的称之为栈上替换(On Stack Replacement,OSR),即方法栈帧还在栈上,方法就被替换了。

2 如何检热点代码

2.1 常见的热点检测方法

对于如何检测热点代码,是不是需要触发即时编译,需要进行Hot Spot Detection(热点探测)。

目前主要的热点探测方式有以下两种:

  1. 基于采样的热点探测

采用这种方法的虚拟机会周期性地检查各个线程的栈顶,如果发现某些方法经常出现在栈顶,那这个方法就是“热点方法”。

这种探测方法的好处是实现简单高效,还可以很容易地获取方法调用关系(将调用堆栈展开即可),缺点是很难精确地确认一个方法的热度,因为容易受到线程阻塞或别的外界因素的影响而扰乱热点探测

  1. 基于计数器的热点探测

采用这种方法的虚拟机会为每个方法(甚至是代码块)建立计数器,统计方法的执行次数,如果执行次数超过一定的阀值,就认为它是“热点方法”。

这种统计方法实现复杂一些,需要为每个方法建立并维护计数器,而且不能直接获取到方法的调用关系,但是它的统计结果相对更加精确严谨。

2.2 HotSpot虚拟机使用的热点探测方法

HotSpot虚拟机中使用的是第二种——基于计数器的热点探测方法。

因此它为每个方法准备了两个计数器:方法调用计数器回边计数器。在确定虚拟机运行参数的前提下,这两个计数器都有一个确定的阈值,当计数器超过阈值溢出了,就会触发JIT编译。

  • 方法调用器
    顾名思义,就是用来统计方法被调用的次数,大致统计流程如下:
    image.png

  • 回边计数器
    它的作用就是统计一个方法中循环体代码执行的次数,在字节码中遇到控制流向后跳转的指令称为“回边”。

3 如何编译为本地代码

将代码编译成本地代码时,Server Compiler和Client Compiler两个编译器的编译过程是不一样的。

  • 对Client Compiler来说,它是一个简单快速的编译器,主要关注点在于局部优化,而放弃许多耗时较长的全局优化手段。
  • 而Server Compiler则是专门面向服务器端的,并为服务端的性能配置特别调整过的编译器,是一个充分优化过的高级编译器
jvm 
更新时间:2020-10-29 09:56:01

本文由 清水河恶霸 创作,如果您觉得本文不错,请随意赞赏
采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
原文链接:http://ql.magic-seven.top/2020/10/29/深入理解jvm原理5哪些代码需要编译.html
最后更新:2020-10-29 09:56:01

评论

Your browser is out of date!

Update your browser to view this website correctly. Update my browser now

×