JAVA晚期(运行期)优化

本文介绍JVM如何识别和优化热点代码,包括方法内联、逃逸分析等技术,及两种热点探测方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JVM运行期优化

Java程序在运行的期间,可能会有某个方法或者代码块的运行特别频繁时,就会把这些代码认定为“热点代码”。为了提高热点代码的执行效率,在运行时JVM会将这些代码编译成与本地平台相关的机器码,并进行各种层次的优化,完成这个任务的编译器称为即时编译器(Just In Time Compiler,JIT编译器)。

即时编译器(JIT)

事实上,现在许多主流的商用虚拟机,都同时包含有解释器与编译器,解释器与编译器两者各有优势。

与解释器相比,编译器会将常运行到的代码编译成本地代码区实现,可以获取更高的执行效率。而当程序运行环境中内存资源限制较大时,可以使用解释执行节约内存,反之可以使用编译执行来提高效率。

解释器和编译器之间还可以通过逆优化退回到解释状态继续执行,因此,在整个虚拟机执行架构中,解释器与编译器经常配合工作。


编译对象与触发条件 
编译对象

在运行过程中会被即使编译器编译的“热点代码”有两类:

1,被多次调用的方法;

2,被多次执行的循环体;

触发条件

判断一段代码是不是为热点代码,是不是需要触发即时编译,这样的行为称为热点探测,但进行热点探测也是不一定要知道方法具体被调用了多少次,目前主要的热点探测判定方法有两种:

1,基于采样的热点探测:虚拟机会周期性地检查各个线程的栈顶,如果发现某个或者某些方法经常出现在栈顶,那这个方法就是“热点发放”。

优点:实现简单,高效。容易获取方法调用方法。

缺点:很难精确的定位一个方法的热点,容易受到线程阻塞或别的外界因素影响而扰乱热点探测。

2,基于计数器的热点探测:虚拟机会为每个方法(甚至是代码块)建立计数器,统计方法的执行次数,如果执行次数超过一定的阈值则认为它是热点方法。

优点:统计结构相对来说更加精准和严谨。

缺点:实现复杂,需要为每个方法建立计数器并维护,而且不能直接获取到方法的调用关系。


编译过程

在默认设置下,无论是方法调用产生即使编译请求,还是OSR编译请求,虚拟机在代码编译器还未完成之前,都仍然将按照解释方式继续执行,而编译动作则在后台的编译线程中进行。 

编译优化技术

1.公共子表达式消除:

如果一个表达式E已经计算过了,并且从先前的计算到现在的E中所有变量的值都没有发生变化,那E的这次出现就成公共子表达式,可以用原先的表达式进行消除。

2.数组边界检查消除

系统将自动进行上下界范围检查。

3.方法内联

把目标方法的代码“复制”到发起调用的方法中,避免发生真实的方法调用。

4.逃逸分析

分析对象的动态作用域,当一个对象在方法被定义后,它可能被外部方法所引用,例如作为调用参数传递给其他方法,称为方法逃逸。甚至还有可能被外部线程访问到,称为线程逃逸。

如果能证明一个对象不会逃逸到方法或线程之外,也就是别的方法或线程无法通过任何途径访问到这个对象,就可以为这个变量进行一些高效的优化:如:栈上分配、同步消除、标量替换等。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值