关于Java平台的一些理解(虚拟机执行引擎)

首先是java平台的两个特点:

1.一次编译,到处运行 :JVM帮助开发者屏蔽了操作系统层面上的细节,跨平台不需要重新编译

 2.自动垃圾回收:java的垃圾回收机制

    提到JVM不得不说Jre和Jdk,Jre是java的运行时环境,主要包含了JVM和java基础类库,而Jdk是jre的超集,里面包含了一些编译工具和调试分析工具

    java的代码执行分为两种,第一种是将源代码编译成字节码文件,然后再运行时通过解释器将字节码文件转为机器码执行(jdk8的模式),另一种是编译执行(直接编译成机器码)。在HotSpot虚拟机中内置了两个即时编译器(JIT)C1和C2,前者时Client Compiler。后者是Server Compiler,默认是采用某个解释器和其中一个编译器结合的模式,可以通过”-cilent“和”-server“参数设置。像上面描述那样的叫混合模式,可以通过”-Xint“强制进入纯解释器的模式,也可以通过”-Xcomp“进入编译器优先的模式。JIT技术是可以在运行时将热点代码的字节码直接编译成机器码而跳过解释的步骤。

    jdk9引入了AOT编译器在编译期直接将所有代码编译成机器码执行,可以实现直接把某个类库编译成二进制文件加速执行。(缺陷在于只支持Linux x64 java base)

    在Hotspot虚拟机里,采用基于计数器的方式确定热点代码,包括方法调用计数器和回边计数器(循环体内代码)

    分层编译策略:程序解释执行(不开启性能监控)可以触发C1编译,将字节码编译成机器码,可以进行简单优化,也可以加上性能监控,C2编译会根据性能监控信息进行激进优化。

    解释执行用于需要迅速启动和执行时,消耗时间短。且作为编译器激进优化的备份方案。而编译器是为了更好的优化代码,提高执行效率,但优化时间一般会比较长。

    C1和C2编译器从优化的程度上是不一样的,C1进行简单、可靠的优化,耗时短。C2进行耗时较长的优化,以及激进优化。但优化的代码执行效率更高。C1同时提供运行时性能监控信息。

    一般在代码触发编译条件以前会使用解释执行,随着运行的时间增长,当触发编译条件时,即时编译器会对代码进行编译,而触发编译器的条件是代码执行的次数够多(达到阈值)。解释执行也在编译器进行激进优化不成立的时候,作为逃生门对代码进行解释执行。

扫描二维码关注公众号,回复: 1853951 查看本文章

    在不同的编译器上有不同的优化策略,C1编译器上主要有方法内联,去虚拟化、冗余消除。

    方法内联就是将引用的函数代码编译到引用点处,这样可以减少栈帧的生成,减少参数传递以及跳转过程

    去虚拟化是对唯一的实现类进行内联

    冗余消除则是在运行期间把一些不会执行的代码折叠掉

    C2的优化主要是在全局层面,逃逸分析是优化的基础(运行时方法中的变量是否会被外部读取)。基于逃逸分析在C2上有如下几种优化:

    标量替换:用标量值代替聚合对象的属性值

    栈上分配:对于未逃逸的对象分配对象在栈而不是堆

    同步消除:清除同步操作,通常指synchronized


猜你喜欢

转载自blog.csdn.net/qq_36243399/article/details/80205701