即时(JIT)

即时(JIT)编译器是Java虚拟机的大脑。 JVM中对JIT编译器的影响最大。

一会儿,让我们退后一步,看看已编译和未编译语言的示例。

诸如Go,C和C ++之类的语言之所以称为编译语言,是因为它们的程序以二进制(编译)代码的形式分发,针对特定的CPU。

另一方面,将解释 PHP和Perl之类的语言。 只要机器具有解释器,就可以在任何CPU上运行相同的程序源代码。 解释器在执行该行时将程序的每一行转换为二进制代码。

Java试图在这里找到中间立场。 Java应用程序已编译,但没有被编译为用于特定CPU的特定二进制文件,而是被编译为bytecode 。 这为Java提供了一种解释语言的平台独立性。 但是Java不止于此。

在典型的程序中,仅一小部分代码会频繁执行,而应用程序的性能主要取决于这些代码部分的执行速度。 这些关键部分被称为应用程序的热点

JVM执行特定代码段的次数越多,有关它的信息就越多。 这使JVM可以做出明智/优化的决策,并将小的热代码编译为CPU特定的二进制文件。 该过程称为即时编译(JIT)

现在,我们运行一个小程序并观察JIT编译。

public class App {public static void main(String[] args) {long sumOfEvens = 0;for(int i = 0; i < 100000; i++) {if(isEven(i)) {sumOfEvens += i;}}System.out.println(sumOfEvens);}public static boolean isEven(int number) {return number % 2 == 0;}
}#### Run
javac App.java && \
java -server \-XX:-TieredCompilation \-XX:+PrintCompilation \- XX:CompileThreshold=100000 App#### Output
87    1             App::isEven (16 bytes)
2499950000

输出告诉我们isEven方法已编译。 我故意禁用了TieredCompilation,以仅获取最常编译的代码。

JIT编译的代码将极大地提高您的应用程序的性能。 要检查吗? 编写一个简单的基准代码。

内联

内联是JIT编译器进行的最重要的优化之一。 内联将方法调用替换为方法的主体,以避免方法调用的开销。

让我们再次运行相同的程序,这次观察内联。

#### Run
javac App.java && \
java -server \-XX:+UnlockDiagnosticVMOptions \-XX:+PrintInlining \-XX:-TieredCompilation App#### Output
@ 12   App::isEven (16 bytes)   inline (hot)
2499950000

再次进行内联将大大提高您的应用程序的性能。

转义分析

转义分析是一种技术,通过该技术JIT编译器可以分析新对象的使用范围,并决定是将其分配在Java堆上还是在方法堆栈上。 它还消除了对所有非全局转义对象的锁定

让我们运行一个小程序,观察垃圾回收。

public class App {public static void main(String[] args) {long sumOfArea = 0;for(int i = 0; i < 10000000; i++) {Rectangle rect = new Rectangle(i+5, i+10);sumOfArea += rect.getArea();}System.out.println(sumOfArea);}static class Rectangle {private int height;private int width;public Rectangle(int height, int width) {this.height = height;this.width = width;}public int getArea() {return height * width;}}
}

在此示例中,矩形对象被创建并且仅在循环内可用,它们的特征是NoEscape,并且将在堆栈而不是堆上分配它们。 具体来说,这意味着不会发生垃圾回收。

让我们在不使用EscapeAnalysis的情况下运行该程序。

#### Run
javac App.java && \
java -server \-verbose:gc \-XX:-DoEscapeAnalysis App#### Output
[GC (Allocation Failure)  65536K->472K(251392K), 0.0007449 secs]
[GC (Allocation Failure)  66008K->440K(251392K), 0.0008727 secs]
[GC (Allocation Failure)  65976K->424K(251392K), 0.0005484 secs]
16818403770368

如您所见,GC已启动。 分配失败意味着年轻一代中没有剩余空间来分配对象。 因此,这是年轻GC的正常原因。

这次让我们使用EscapeAnalysis运行它。

#### Run
javac App.java && \
java -server \-verbose:gc \-XX:+DoEscapeAnalysis App#### Output
16818403770368

这次没有发生GC。 从根本上讲,这意味着创建寿命短且作用域狭窄的对象不一定会引入垃圾。

默认情况下启用DoEscapeAnalysis选项。 请注意,只有Java HotSpot Server VM支持此选项。

因此,我们所有人都应避免过早的优化,而应专注于编写更具可读性/可维护性的代码,并让JVM发挥作用。

翻译自: https://www.javacodegeeks.com/2015/12/jit-compiler-inlining-escape-analysis.html

JIT编译器,内联和转义分析相关推荐

  1. jit 方法内联_JIT编译器,内联和转义分析

    jit 方法内联 即时(JIT) 即时(JIT)编译器是Java虚拟机的大脑. JVM中对JIT编译器的影响最大. 一会儿,让我们退后一步,看看已编译和未编译语言的示例. 诸如Go,C和C ++之类的 ...

  2. 一个go1.9.x 编译器内联引起的栈信息错乱的问题分析

    2019独角兽企业重金招聘Python工程师标准>>> 背景是在写个日志库,日志库有个很重要的功能就是要打印出调用栈,知道具体是哪个文件,哪个函数调用的Info 等. 然后在测试中发 ...

  3. C++对象模型9——临时对象的生命周期、模板及实例化分析、内联函数

    一.临时对象的生命周期 T c=a+b 假设T是一个类型,那么上述代码执行时,首先会产生一个临时对象用来存放a+b的结果(拷贝初始化临时对象),然后用该临时对象拷贝初始化c,最后临时对象被释放.如果开 ...

  4. JVM原理(二)执行引擎篇(JVM程序执行流程、JIT编译器、JIT编译器优化)

    一.JVM程序执行流程 上一章我们介绍过程序执行通常分为解释执行和编译执行,而Java两种方式都采用了,下面是Java编译成字节码.动态编译和解释为机器码的过程分析: 编译器和解释器的协调工作流程: ...

  5. c++学习笔记内联函数,函数重载,默认参数

    c++学习笔记内联函数,函数重载,默认参数 1 inline内联函数 C++中的const常量可以替代宏常数定义,如: const int A = 3;  #define A 3 C++中是否有解决 ...

  6. 解密新一代Java JIT编译器Graal

    \ 关键要点 \\ Java的C2 JIT编译器寿终正寝.\\t 新的JVMCI编译器接口支持可插拔编译器.\\t 甲骨文开发了Graal,一个用Java编写的JIT,作为潜在的编译器替代方案.\\t ...

  7. C++内联函数(inline function)

    c++从c中继承的一个重要特征就是效率.假如c++的效率明显低于c的效率,那么就会有很大的一批程序员不去使用c++了. 在c中我们经常把一些短并且执行频繁的计算写成宏,而不是函数,这样做的理由是为了执 ...

  8. C++ 内联函数详解(搞清内联的本质及用法)

    目录 一.什么是内联函数 1.直观上定义: 2.更深入的思考: 二.为什么使用内联函数 1.为什么要代替部分宏定义 2.普通函数频繁调用的过程消耗栈空间 3.更深入的思考 三.内联函数和编译过程的相爱 ...

  9. C++中虚函数可以是内联函数吗?

    1.需要注意的几点: 虚函数可以是内联函数,内联是可以修饰虚函数的,但是当虚函数表现多态性的时候不能内联. 内联是在编译器建议编译器内联,而虚函数的多态性在运行期,编译器无法知道运行期调用哪个代码,因 ...

最新文章

  1. 2D景观转3D风景大片,无惧复杂光线与遮挡,人类离「躺着旅行」的梦想又近了一步...
  2. 调用webservice或wcf时,提示:无法加载协定为的终结点配置部分,因为找到了该协定的多个终结点配置。请按名称指示首选的终结点配置部分。
  3. DataSet转化为DataTable
  4. python asyncio和celery对比_如何将Celery与asyncio结合? - python
  5. 【数字逻辑设计】多级组合逻辑电路减少硬件
  6. Android两种获取IP地址的方式(使用WIFI和GPRS)
  7. burp抓包mumu模拟器
  8. CTF-PHP反序列化漏洞2-利用魔法函数
  9. 每日学习 与 每日未知
  10. 16bit灰度图像映射到8bit显示
  11. 电磁场与电磁波 复习(3-4)
  12. 2021年安全员-A证复审考试及安全员-A证考试试题
  13. 决策树中基尼不纯度初步理解
  14. 【BZOJ1492】【NOI2007】—Cash(cdq分治维护凸包优化斜率dp)
  15. 2017年Q1全球平均固定互联网速度达7.2Mbps 同比增15%
  16. [洛谷] P1508 吃吃吃
  17. oracle闪回能保存多长时间,Oracle闪回
  18. 海伯利安系列解答之 - Map3和泰坦
  19. 硕士毕业论文常见的排版小技巧
  20. 长隆大马戏机器人_惊“戏”开启广州长隆国际大马戏“魔幻圣诞月”

热门文章

  1. System.gc()调用 - 适用的场景
  2. Sentinel控制台
  3. 微信消息提醒与消息数字提示之BadgeView
  4. zookeeper  虚拟机zookeeper和 win10java代码连接
  5. docker export_docker使用简介
  6. 转:Redis 集群搭建详细指南
  7. es dsl多条件组合查询(转)
  8. 2017尼毕鲁笔试算法题
  9. java联接pg库_成为Java流大师–第5部分:将联接的数据库表转换为流
  10. 日发帖 发帖频率 发帖时段_先发帖