IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 侃侃编译器优化 -> 正文阅读

[Java知识库]侃侃编译器优化

字节码是如何运行的?

首先我们先探讨一下字节码是如何运行的,众所周知,java有两种运行模式,一种叫解释执行,一种叫编译执行:

  • 解释执行:由编译器一行一行翻译执行
  • 编译执行:把字节码翻译成机器码,直接执行机器码

下面我们来对比一下这两种执行模式:

  • 解释执行:
    • 优势在于没有编译的等待时间
    • 性能相对差一些
  • 编译执行:
    • 运行效率会高很多,一般认为比解释执行快一个数量级
    • 带来了额外开销

那么怎样去查询Java是解释执行还是编译执行的呢?
很简单,执行 java -version就可以了
在这里插入图片描述
我们可以看到有一个 mixed mode 表示混合模式,表示部分代码解释执行,部分代码编译执行。
你可以使用-Xint:把JVM的执行模式设置为解释执行模式
也可以使用 -Xcomp:JVM优先以编译模式运行,不能编译的,以解释执行模式运行。
也可以使用-Xmixed:让JVM以混个模式运行,默认情况下就是混合模式。

JVM如何优化解释器?

在一般情况下

  • 一开始由解释器解释执行
  • 当虚拟机发现某个方法或代码块的运行特别频繁的时候,就会认为这些代码是“热点代码”。为了提高热点代码的执行效率,会用即时编译器(也就是JIT)把这些热点代码编译成本地平台相关的机器码,并进行各层次的优化

就目前来说,Hostpot虚拟机内置了两个编译器,也就是C1编译器和C2编译器:

  • C1编译器:
    • 是一个简单快速的编译器
    • 主要关注局部性的优化
    • 适用于执行时间比较短或对启动性能有要求的程序。例如,GUI应用对界面启动速度就有一定的要求。
    • 也被称为Client Complier
  • C2编译器:
    • 是为长期运行的服务器端应用程序做性能调优的编译器
    • 适用于执行时间较长或对峰值性能有要求的程序
    • 也被称为是Server Complier

各层次优化指的是哪些优化?

从JDK7开始,正式引入了分层编译的概念,可以细分为五种编译级别

  • 0:解释执行
  • 1:简单C1编译:会用C1编译器进行简单优化,不开启profiling(JVM性能监控)
  • 2:受限的C1编译:仅执行带方法调用次数以及循环回边执行次数Profiling的C1编译
  • 3:完全C1编译:会执行带有所有Profiling的C1代码
  • 4:C2编译:使用C2编译器进行优化,该级别会启用一些编译耗时比较长的优化,一些情况下会根据性能监控信息进行一些非常激进的性能优化

一般来说级别越高,应用启动越慢,优化的开销越高,峰值性能也越高

分层编译-JVM参数配置

默认情况下,JDK8是开启分层编译的

  • 只想开启C2:-XX:-TieredCompilation(禁用中间编译层(123层))
  • 只想开启C1:-XX:+TieredCompilation -XX:TieredStopAtLevel=1

如何找到热点代码?

前面提到过,编译执行主要是针对热点代码的,那么如何找到这些热点代码呢?
就目前来说,业界对于找到热点代码的思路有两种

  1. 基于采样的热点探测
    大致思路是:周期检查各个线程的栈顶,如果某个方法经常出现在栈顶,那么就会认为这个方法是热点方法。
  2. 基于计数器的热点探测
    大致思路是为每个方法或者代码块建立计数器, 统计执行的次数,如果超过一定阈值,那么就会认为它是热点方法。

Hotspot虚拟机是采用的基于计数器的热点探测。

Hotspot内置的两类计数器

  • 方法调用计数器(Invocation Counter)
    • 用于统计方法被调用的次数,在不开启分层编译的情况下,在C1编译器下的默认阈值是1500次,在C2模式下是10000次。也可用-XX:CompileThreshold=X执行阈值
  • 回边计数器(Back Edge Counter)
    • 用于统计一个方法中循环体代码执行的次数,在字节码中遇到控制流向后跳转的指令称为"回边"(Back Edge)。在不开启分层编译的情况下,C1编译器下的默认阈值13995,C2默认为10700,可使用-XX:OnStackReplacePercentage=X指定阈值
    • 建立回边计数器的主要目的是为了触发OSR(OnStackReplacement)编译

当开启分层编译,JVM会根据当前待编译的方法数以及编译线程数来动态调整阈值,-XX: CompileThreshold、-XX:OnStackReplacePercentage都会失效

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-20 12:21:41  更:2021-10-20 12:22:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:24:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码