【JVM】执行引擎、JIT、逃逸分析(二)

2024-08-29 14:04

本文主要是介绍【JVM】执行引擎、JIT、逃逸分析(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

执行引擎、JIT、逃逸分析

JIT(Just-In-Time,即时编译)

在这里插入图片描述

针对的是热点代码(触发JIT的条件)
Client模式:32bit才有
Server模式:64bit
触发条件后,谁来编译,编译线程
C1:Client模式下
C2: Server模式下
JDK6之后,混合在一起,
热点代码((统计的并不是被调用的绝对次数,而是一个相对的执行频率,一段时间内方法被调用的次数))其中包括

  • 1.方法
  • 2.代码块 循环
    Client模式下:1500次执行触发
    Server模式下:10000次执行JIT及时编译
    JIT的底层实现,达到条件之后会以异步队列的方式Queue封装成VM:Operation入队,然后叫i给VM:Thread:loop

但是热点代码会有一个热度衰减的概念,
比如执行了7000次,在执行3001次之后触发JIT,但是过了1min之后,可能需要执行6501次才可以,相当于1min前的7000次衰减为了3500次
热度衰减的原因:确保是热点代码,不然触发JIT的代码会越来越多

方法调用计数器触发即时编译

在这里插入图片描述

查看及分析即时编译结果(需要开启VM 参数-XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation -XX:+PrintInlining)

public class JITTest {public static final int NUM = 15000;public static int doubleValue(int i) {// 这个空循环用于后面演示JIT代码优化过程for (int i1 = 0; i1 < 100000; i1++);return i * 2;}public static long calcSum() {long sum = 0;for (int i = 0; i < 100000; i++) {sum += doubleValue(i);}return sum;}public static void main(String[] args) {for (int i = 0; i < NUM; i++) {calcSum();}}
}

在这里插入图片描述

带%的输出说明是由回边计数器触发的即时编译,可以看到calcSum()和doubleValue()方法都已经被即时编译,并且还看到了doubleValue方法已经被内联编译到calcSum()方法中

热点代码缓存区

热点代码缓存时保存在方法区的,这块也是调优需要调的地方
server编译器模式下代码缓存大小起始于2496KB
client编译器模式下代码缓存大小起始于160KB

热机且冷机故障(热机在崩溃的边缘)

新加的机器,流量切过去之后,就挂了。热机运行了很长时间。冷机才刚运行不久。冷机字节码解释器模式,CPU升高就挂了
原因:Java刚启动时,一段时间触发JIT之后,性能才会达到最高。
怎么解决呢?
1.缓缓的切流量,慢慢测
2.加更多的机器。
JIT触发,会将多个执行流合并

逃逸分析

逃逸分析(Escape Analysis)是目前Java虚拟机中比较前沿的优化技术,它与类继承关系分析一样,并不是直接优化代码的手段,而是为其他优化手段提供依据的分析技术。
逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他方法中,称为方法逃逸。甚至还有可能被外部线程访问到,比如赋值给类变量或可以在其他线程中访问的实例变量,称为线程逃逸。
如果能证明一个对象不会逃逸到方法或线程之外,也就是别的方法或线程无法通过任何途径访问到这个对象,则可能为这个变量进行一些高效的优化,如下所示:

  • 1.栈上分配(Stack Allocation)
    Java虚拟机中,在Java堆上分配创建对象的内存空间几乎时Java程序员都清除的常识了,Java堆中的对象对于各个线程都是共享和可见的,只要持有这个对象的引用,就可以访问堆中存储的对象数据。虚拟机的垃圾收集系统可以回收堆中不再使用的对象,但回收动作无论是筛选可回收对象,还是回收和整理内存都需要耗费时间。如果一个对象不会逃逸出方法之外,那让这个对象在栈上分配内存将会是一个很不错的注意,对象所占用的内存空间就可以随栈帧出栈而销毁。在一般应用中,不会逃逸的局部对象所占的比例很大,如果能使用栈上分配,那大量的对象就会随着方法的结束而自动销毁了,垃圾收集系统的压力将会小很多。
  • 2.同步消除(Syncrhonization Elimination):线程同步本身是一个相对耗时的过程,如果逃逸分析能够确定一个变量不会逃逸出线程,无法被其他线程访问,那这个变量的读写肯定就不会有竞争,堆这个变量实施的同步措施也就可以消除掉
  • 3.标量替换(Scalar Replacement):标量(Scalar)是指一个数据已经无法再分解成更小的数据来表示了,Java虚拟机中的原始数据类型(int、long等数值类型以及类型reference类型等)都不能再进一步分解,它们就可以称为标量。相对的,如果一个数据可以继续分解,那它就称做聚合量(Aggregate),Java中的对象就是最典型的聚合量。如果把一个Java对象拆散,根据程序访问的情况,将其使用到的成员变量恢复原始类型来访问就叫做标量替换。如果逃逸分析证明一个对象不会被外部访问,并且这个对象可以被拆散的话,那程序真正执行的时候将可能不创建这个对象,而改为直接创建它的若干个被这个方法使用到成员变量来代替。将对象拆分后,除了可以让对象的成员变量在栈上(栈上存储的数据,有很大的概率会被虚拟机分配至物理机器的高速寄存器中存储)分配和读写之外,还可以为后续进一步的优化手段创建条件。

在早期阶段,这项技术还不够成熟,原因主要是不能保证逃逸分析的性能收益必定高于它的消耗。如果要完全准确地判断一个对象是否会逃逸,需要进行数据流敏感的一系列复杂分析,从而确定程序各个分支执行时对此对象的影响。这是一个相对高耗时的过程,如果分析完后发现没有几个不逃逸的对象,那这些运行期好用的时间就白白浪费了。

如何查看

在这里插入图片描述
开始栈上分配,创建100w个对象,HSDB查看对象的数量,只有11w个对象

在这里插入图片描述
关闭栈上分配

这篇关于【JVM】执行引擎、JIT、逃逸分析(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1118062

相关文章

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

Java操作Word文档的全面指南

《Java操作Word文档的全面指南》在Java开发中,操作Word文档是常见的业务需求,广泛应用于合同生成、报表输出、通知发布、法律文书生成、病历模板填写等场景,本文将全面介绍Java操作Word文... 目录简介段落页头与页脚页码表格图片批注文本框目录图表简介Word编程最重要的类是org.apach

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP

SpringBoot+Docker+Graylog 如何让错误自动报警

《SpringBoot+Docker+Graylog如何让错误自动报警》SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK... 目录01 Spring Boot 默认日志框架解析02 Spring Boot 日志级别详解03 Sp

java中反射Reflection的4个作用详解

《java中反射Reflection的4个作用详解》反射Reflection是Java等编程语言中的一个重要特性,它允许程序在运行时进行自我检查和对内部成员(如字段、方法、类等)的操作,本文将详细介绍... 目录作用1、在运行时判断任意一个对象所属的类作用2、在运行时构造任意一个类的对象作用3、在运行时判断

java如何解压zip压缩包

《java如何解压zip压缩包》:本文主要介绍java如何解压zip压缩包问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java解压zip压缩包实例代码结果如下总结java解压zip压缩包坐在旁边的小伙伴问我怎么用 java 将服务器上的压缩文件解压出来,

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具

Spring WebFlux 与 WebClient 使用指南及最佳实践

《SpringWebFlux与WebClient使用指南及最佳实践》WebClient是SpringWebFlux模块提供的非阻塞、响应式HTTP客户端,基于ProjectReactor实现,... 目录Spring WebFlux 与 WebClient 使用指南1. WebClient 概述2. 核心依