Java面试之Java是解释执行的吗?

Java 发表评论

一、个人观点

   这个说法不够准确,Java源代码首先通过Javac编译成相应的字节码(bytecode),然后,在运行时,通过JVM内嵌的解释器将字节码转换为最终的机器码,然后进行执行,这部分是解释执行。但是常见的JVM(比如Hotspot JVM)提供了JIT(Just-In-Time  动态编译器),JIT能够在运行时将热点代码编译成机器码,这部分热点代码就属于编译执行的。故,总体上说,现在的Java是”解释+编译”执行的。

 

二、判断一段代码是否是热点代码的方式:
①基于采样的热点探测。
②基于计数器的热点探测:采用这种方法的虚拟机会为每个方法建立计数器,统计方法的执行次数,如果执行次数超过一定的阈值就认为它是热点方法。方法调用计数器统计的并不是方法被调用的绝对次数,而是一个相对的执行频率,也就是一段时间内方法被调用的次数。当超过一定的时间限度,如果方法的调用次数仍然不足以让它提交给即时编译器编译(JIT编译当某段代码即将第一次被执行时进行编译),那这个方法的调用计数器就会被减少一半,这个过程称为方法调用计数器的热度的衰减,而这段时间就成为此方法统计的半衰周期,进行热度衰减的动作在虚拟机进行垃圾收集时顺便进行了。

注意:

        ①JIT编译(即时编译)是动态编译的一个特例。

        ②动态编译:在运行时编译。

        ③自适应动态编译:先让程序以某种方式运行起来,然后收集一些信息之后再进行动态编译。

三、判断一段循环体代码是否为热点代码的方式:
①使用回边计数器计数。

    作用:统计一个方法体重循环体代码执行的次数,在字节码中遇到控制流向后跳转的指令成为回边,显然,建立回边计数器统计的目的就是为了触发OSR编译。没有计数热度衰减的过程,因此这个计数器统计的就是该方法执行循环的绝对次数,当计数器溢出的时候,它还会把方法计数器的值也调整到溢出的状态,这样下次在再进入该方法的时候就会执行标准编译过程。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

昵称 *