首页 > 其他分享 >JVM中的编译器

JVM中的编译器

时间:2023-04-20 22:25:19浏览次数:38  
标签:Graph Server 编译器 JVM C2 优化 Compiler

JVM中集成了两种编译器,Client Compiler和Server Compiler,它们的作用也不同。Client Compiler注重启动速度和局部的优化,Server Compiler则更加关注全局的优化,性能会更好,但由于会进行更多的全局分析,所以启动速度会变慢。两种编译器有着不同的应用场景,在虚拟机中同时发挥作用。

Client Compiler

HotSpot VM带有一个Client Compiler C1编译器。这种编译器启动速度快,但是性能比较Server Compiler来说会差一些。C1会做三件事:

  • 局部简单可靠的优化,比如字节码上进行的一些基础优化,方法内联、常量传播等,放弃许多耗时较长的全局优化。
  • 将字节码构造成高级中间表示(High-level Intermediate Representation,以下称为HIR),HIR与平台无关,通常采用图结构,更适合JVM对程序进行优化。
  • 最后将HIR转换成低级中间表示(Low-level Intermediate Representation,以下称为LIR),在LIR的基础上会进行寄存器分配、窥孔优化(局部的优化方式,编译器在一个基本块或者多个基本块中,针对已经生成的代码,结合CPU自己指令的特点,通过一些认为可能带来性能提升的转换规则或者通过整体的分析,进行指令转换,来提升代码性能)等操作,最终生成机器码。

Server Compiler

Server Compiler主要关注一些编译耗时较长的全局优化,甚至会还会根据程序运行的信息进行一些不可靠的激进优化。这种编译器的启动时间长,适用于长时间运行的后台程序,它的性能通常比Client Compiler高30%以上。目前,Hotspot虚拟机中使用的Server Compiler有两种:C2和Graal。

C2 Compiler

在Hotspot VM中,默认的Server Compiler是C2编译器。

C2编译器在进行编译优化时,会使用一种控制流与数据流结合的图数据结构,称为Ideal Graph。 Ideal Graph表示当前程序的数据流向和指令间的依赖关系,依靠这种图结构,某些优化步骤(尤其是涉及浮动代码块的那些优化步骤)变得不那么复杂。

Ideal Graph的构建是在解析字节码的时候,根据字节码中的指令向一个空的Graph中添加节点,Graph中的节点通常对应一个指令块,每个指令块包含多条相关联的指令,JVM会利用一些优化技术对这些指令进行优化,比如Global Value Numbering、常量折叠等,解析结束后,还会进行一些死代码剔除的操作。生成Ideal Graph后,会在这个基础上结合收集的程序运行信息来进行一些全局的优化,这个阶段如果JVM判断此时没有全局优化的必要,就会跳过这部分优化。

无论是否进行全局优化,Ideal Graph都会被转化为一种更接近机器层面的MachNode Graph,最后编译的机器码就是从MachNode Graph中得的,生成机器码前还会有一些包括寄存器分配、窥孔优化等操作。关于Ideal Graph和各种全局的优化手段会在后面的章节详细介绍。Server Compiler编译优化的过程如下图所示:

Graal Compiler

从JDK 9开始,Hotspot VM中集成了一种新的Server Compiler,Graal编译器。相比C2编译器,Graal有这样几种关键特性:

  • 前文有提到,JVM会在解释执行的时候收集程序运行的各种信息,然后编译器会根据这些信息进行一些基于预测的激进优化,比如分支预测,根据程序不同分支的运行概率,选择性地编译一些概率较大的分支。Graal比C2更加青睐这种优化,所以Graal的峰值性能通常要比C2更好。
  • 使用Java编写,对于Java语言,尤其是新特性,比如Lambda、Stream等更加友好。
  • 更深层次的优化,比如虚函数的内联、部分逃逸分析等。

Graal编译器可以通过Java虚拟机参数-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler启用。当启用时,它将替换掉HotSpot中的C2编译器,并响应原本由C2负责的编译请求。

 

参考原文:基本功 | Java即时编译器原理解析及实践 - 美团技术团队 (meituan.com)

 

标签:Graph,Server,编译器,JVM,C2,优化,Compiler
From: https://www.cnblogs.com/FangwayLee/p/17338548.html

相关文章

  • 【Azure Spring Cloud】在Azure Spring Apps上看见 App Memory Usage 和 jvm.menory.u
    问题描述在Azure的SpringCloud服务(官名为:SpringApps)中,在Metrics页面中查看AppMemoryUsage和jvm.memory.use,发现两则在下图中出现巨大差距。AppMemoryUsage还是在逐渐上升jvm.memory.use却断崖式下降  在AppMemoryUsage在逐渐上涨的情况下,是否会最终出现OO......
  • JVM技术 反射与动态代理
    评:动态代理Sun对动态代理的说明:一个简单例子代码:动态代理的内部实现——代码生成:研究JDK源代码,发现在Proxy的sun实现中调用了sun.misc.ProxyGenerator类的generateProxyClass(proxyName,interfaces)方法,其返回值为byte[]和class文件的内存类型一致。于是做如下试......
  • 一次线上JVM调优实践的优化过程
    通过这一个多月的努力,将FullGC从40次/天优化到近10天才触发一次,而且YoungGC的时间也减少了一半以上,这么大的优化,有必要记录一下中间的调优过程。对于JVM垃圾回收,之前一直都是处于理论阶段,就知道新生代,老年代的晋升关系,这些知识仅够应付面试使用的。前一段时间,线上服务器的FullGC......
  • 一天吃透JVM面试八股文
    什么是JVM?JVM,全称JavaVirtualMachine(Java虚拟机),是通过在实际的计算机上仿真模拟各种计算机功能来实现的。由一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域等组成。JVM屏蔽了与操作系统平台相关的信息,使得Java程序只需要生成在Java虚拟机上运行的目标......
  • 编译器指令重排序问题(使用编译器屏障)
    环境:Windows平台:win7_64旗舰版、VS2019Linux平台:CentOSLinuxrelase7.2.1511、GCC_4.8.5-4场景:为了提高性能,编译器会对指令进行重新排序,在多线程环境下指令的乱序执行会造成无法预测的行为。开始:一、指令重排序实例inta=0,b=0;voidtest(){a=......
  • Java JVM、JNI、Native Function Interface、Create New Process Native Function API
    JavaJVM、JNI、NativeFunctionInterface、CreateNewProcessNativeFunctionAPIAnalysis目录1.JAVAJVM2.JavaJNI:JavaNativeInterface3.JavaCreateNewProcessNativeFunctionAPIAnalysisInLinux4.JavaCreateNewProcessNativ......
  • JVM系统优化实践(16):线上GC案例
    您好,我是湘王,这是我的51CTO博客,欢迎您来,欢迎您再来~列举几个实际使用案例说一下GC的问题。一个高峰期每秒10万QPS的社交APP,个人主页模块是流量最大的那个,而一次个人主页的查询,大概会加载5M的数据。由于并发量太高,导致高峰期年轻代的Eden区被迅速填满,且频繁触发YoungGC,每次YoungGC......
  • JVM vs JDK vs JRE
    JVM(JavaVirtueMachine)是运行Java字节码的虚拟机。JVM有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。字节码和不同系统的JVM实现是Java语言“一次编译,随处可以运行”的关键所在。JVM并不是只有一种!只要满足JVM规范,每......
  • c编译器五个没有参数的宏
    _LINE_十进制整数常量,表示当前源程序代码的行号_FILE_字符串常量,表示当前源文件名_DATE_字符串常员,表示当前日期,格式为:"mmmddyyyy"_TIMESTAMP字符串常量,表示最后一次修改源文件的日期和时间,格式为:DddMmmhh:mm:ssyyyy_STDC_如果编译器与ANSIC兼......
  • 深入理解 JVM --- Class 类文件结构
    各种不同平台的Java虚拟机,以及所有平台都统一支持的程序存储格式——字节码(ByteCode)是构成平台无关性的基石。时至今日,商业企业和开源机构已经在Java语言之外发展出一大批运行在Java虚拟机之上的语言,如Kotlin、Clojure、Groovy、JRuby、JPython、Scala等。实现语言无关性的基......