首页 > 编程语言 >【Java的JIT技术】

【Java的JIT技术】

时间:2024-11-15 20:20:27浏览次数:3  
标签:Java int 代码 技术 class JIT 逃逸 Test public

JIT(Just In Time)编译器, 也称即时编译器, 主要在JVM运行时期动态的做一些优化提升代码的运行速度和效率。

大家都知道, jvm运行时是通过解释器将每一条class字节码指令翻译成机器指令去执行。
JIT则不同, 它会在jvm运行时期动态的将热点代码编译成机器指令, 缓存下来. 之后每次执行这段代码时, 直接执行对应的机器码, 无需再次编译。
要注意的是, JIT并不是jvm一启动就工作, 因为它需要检测出哪些是热点代码, 所以一般需要jvm运行一段时间才开始工作。(所以有时候服务刚启动时, 会感觉很慢, 执行一段时间又感觉变快了, 可能就是这个原因)

1、热点代码检测

一般有两种方式:

  • 采样探测
    定期去线程的栈顶检测, 频繁出现在栈顶的方法会被判定为热点方法。这种方式简单但是不精准, 且会受线程阻塞影响。
  • 计数器探测
    给每个方法或代码块创建一个计数器, 统计执行次数, 超过阈值就判定为热点代码。进行编译缓存。

另外JIT编译器还会通过逃逸分析、标量替换、栈上分配、内联优化、同步消除、锁消除等多种手段,提升执行效率。使Java程序在保证跨平台特性的同时,能够接近原生编译代码的执行效率。

2、逃逸分析

可以通过启动参数进行设置
-XX:+DoEscapeAnalysis 开启
-XX:-DoEscapeAnalysis 关闭

2.1、全局逃逸
一般发在全局变量上、或者方法的返回值上

class Test{
	public static Object obj;

	public void updateRes(){
		obj = new Object();
	}

	public static Job createJob(){
		Job job = new Job();
		...
		return job;
	}
}

2.2、参数逃逸
一般发生在对象被作为参数传递代码中

class Test{
	public JobDto getJobDto(){
		JobDto jobDto = assemble2JobDto(jobInfo);
		return jobDto;
	}

	public JobDto assemble2JobDto(JobInfo jobInfo){
		//jobInfo对象从getJobDto方法逃逸到本方法,且未发生全局逃逸
		...
		return jobDto;
	}
}

2.3、无逃逸
方法中的对象没有发生逃逸,对象的作用范围在一个方法体内

class Test{
	public String getJobTitle(Long jobId){
		JobInfo jobInfo = getJobInfo(jobId); // jobInfo对象并为作为返回值, 逃逸出方法外
		String jobTitle = jobInfo.getJobTitle();
		return jobTitle;
	}
}

3、标量替换

如果逃逸分析确定某个对象可以被分解为多个基本类型变量(标量),那么这些变量可以直接在栈上分配,减少堆内存的占用。

class Test{

	public void printNum(){
		JobRate jobRate = new JobRate(20,30);
		int ratePer = rate.getMaxRate() - rate.getMinRate();
	}
	
	class JobRate{
		private int minRate;
		private int maxRate;
	}
}

这段代码经过逃逸分析后, 发现jobRate对象未发生逃逸, 且可以被拆分为标量, 那么就可以不用创建JobRate对象, 直接进行标量替换去计算

class Test{

	public void printNum(){
		int minRate = 20;
		int maxRate = 30;
		int ratePer = maxRate - minRate;
	}
	

4、栈上分配

如果逃逸分析确定某个对象不会逃逸出方法,那么这个对象可以在栈上分配内存,而不是在堆上。方法执行完毕,对象的内存立即释放,这可以避免垃圾收集器的介入,减少垃圾回收的开销。
一般发生在循环中临时对象创建时。

5、同步消除/锁消除

如果逃逸分析确定某段代码中的锁不会被其他线程访问,那么这个锁可以被消除。

class Test{
	public void RedeemPrize(){
		object lock = new Object();
		synchronized(lock){
			int accPoints = getAccPoints();
			...
		}
	}
}

上面这段代码, 经过逃逸分析, lock对象没有发生逃逸, 且不会被其他线程访问到, 会被进行优化

class Test{
	public void RedeemPrize(){
		int accPoints = getAccPoints();
		...
	}
}

6、内联优化

将方法的调用替换为方法的具体代码,主要是为了节省方法调用时的栈开销,包括创建栈帧、读写寄存器、栈溢出检测等

class Test{

	public int ratePer(int minRate, int maxRate){
		return maxRate - minRate;
	}
	
	public void CommissionPayout(){
		int ratePer = ratePer(20, 30);
	}
}

以上代码经过JIT优化会变成

class Test{
	public void CommissionPayout(){
		int ratePer = 30 - 20;
	}
}

标签:Java,int,代码,技术,class,JIT,逃逸,Test,public
From: https://blog.csdn.net/weixin_44541808/article/details/143774559

相关文章

  • Springboot 整合 Java DL4J 打造金融风险评估系统
    ......
  • LeetCode100之两数相加(2)--Java
    1.问题描述        给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字0之外,这两个数都不会以0 开头。     ......
  • Java 21和Java 8在洛谷上的区别
    Java21默认开大内存很容易遇到所以如果换成Java8最后一个我也不知道为啥,有大佬帮忙看一下吗逆序对-洛谷importjava.util.*;publicclassMain{  staticScannercin=newScanner(System.in);  //非递归版本的归并排序,返回逆序对的数量  publics......
  • 【AI声音克隆整合包及教程】第二代GPT-SoVITS V2:技术、应用与伦理思考
    一、引言在当今科技迅速发展的时代,声音克隆技术成为人工智能领域的一个备受瞩目的分支。GPT-SoVITSV2作为一种声音克隆工具,正逐渐进入人们的视野,它在多个领域展现出巨大的潜力,同时也引发了一系列值得深入探讨的问题。本文旨在介绍GPT-SoVITSV2的技术原理、应用领域及其带来......
  • JavaFX史上最全教程 - Shape - JavaFX路径
    JavaFX有其他内置的形状,如ArcCircleCubicCurveEllipseLinePathPolygonPolylineQuadCurveRectangleSVGPathText以下代码显示了如何创建路径。importjavafx.application.Application;importjavafx.geometry.Insets;importjavafx.scene.Group;importjavafx.scene.Scene;......
  • Loom开篇:Java 虚拟机的协程和延续
    在jdk19发布的时候,java推出了一种全新的线程模型。说是全新的也只是针对java自己而言的。实际上其他语言早就有了类似的实现。这个东西其实就是协程,在java中叫做虚拟线程。jdk中虚拟线程主要是projectloom(以下称为loom)实现的。本文我们针对一篇jdk博客的翻译来打开虚拟......
  • 【一键整合包及教程】AI照片数字人工具EchoMimic技术解析
    在数字化时代,人工智能(AI)正以前所未有的速度改变着我们的生活。EchoMimic,作为蚂蚁集团旗下支付宝推出的开源项目,不仅为数字人技术的发展掀开了新的一页,更为娱乐、教育、虚拟现实、在线会议等多个领域带来了全新的可能性。EchoMimic技术概述EchoMimic是一款基于音频驱动的肖像......
  • java 反序列化 cc7 复现
    复现环境:common-collections版本<=3.2.1,java版本随意.cc7就是cc6换了一个出口,整体的逻辑没有太大的变化.在Lazymap之前的还那样,我们从如何触发Lazymap的get方法开始看起.AbstractMap看他的equals方法publicbooleanequals(Objecto){if(o==this)ret......
  • JAVA部分基础知识点(四)【持续更新】
    1.方法重写当子类觉得父类中的某个方法不好用,或者无法满足自己的需求时,子类可以重写一个方法名称、参数列表一样的方法,去覆善父类的这个方法,这就是方法重写。【注意:重写后,方法的访问,Java会遵循就近原则】方法重写的其它注意事项:重写小技巧:使用Override注解,他可以指定java......
  • Java概述
    1.Java程序编写和执行的过程:步骤1:编写。Java代码编写在.Java结尾的文件中。步骤2:编译。格式:javac源文件名.java步骤3:运行。格式:java字节码文件名2.编写的说明:classHelloWorld{publicstatic.void.main(String[]args){System.out.println("helloworld!!你好中国!");}......