JIT、逃逸分析、锁消除、栈上分配和标量替换等都属于 JVM 的优化手段,JVM 优化手段是指在运行 Java 程序时,通过对字节码的编译和执行过程进行优化,以提升程序的性能和效率。
JVM 优化手段主要有以下几个:
JIT 优点包含以下两个:
在 HotSpot 虚拟机中,热点代码(Hot Code)是指那些被频繁执行的代码。 热点代码的执行次数在不同的 JDK 版本和不同的 JVM 中是不同的,例如,它在 JDK 21 Client 模式下为 1500 次,Server 模式下为 10000 次,这个值可以通过 JVM 参数设置。 通常来说,热点代码的识别基于以下两种策略:
可以使用 java -XX:+PrintFlagsFinal -version 命令查看 JVM 默认配置。
栈上分配和标量替换是编译器的两种优化技术,它们虽然有一些相似之处,但并不完全相同。
也就是说栈上分配,只是将对象从堆上分配到栈上了;而标量替换是更进一步的优化技术,将对象拆解成基本类型分配到栈上了。
锁消除(Lock Elimination)也叫做同步消除,是一种编译器优化技术,它可以消除对于变量的不必要的锁定操作。锁消除的目的是减少锁的开销,提高程序的性能。 例如以下代码:
public void method() {
Object lock = new Object();
synchronized(lock){
System.out.println("www.javacn.site");
}
}
而锁消除之后的代码如下:
public void method(){
System.out.println("www.javacn.site");
}
未优化前的代码如下:
private static class Point {
private int x;
private int y;
}
public static void main(String[] args) {
Point point = createPoint(10, 20);
int sum = point.x + point.y;
System.out.println("Sum: " + sum);
}
private static Point createPoint(int x, int y) {
Point point = new Point();
point.x = x;
point.y = y;
return point;
}
标量替换优化后的代码如下:
public static void main(String[] args) {
int x = 10;
int y = 20;
int sum = x + y;
System.out.println("Sum: " + sum);
}
通过逃逸分析的优化能够减少垃圾回收的压力、减少内存分配和释放带来的性能损耗,并且有可能减少对锁的依赖,以及实现标量替换等,从而整体上提升了应用程序的运行效率。
Java 为什么不把所有代码提前都编译成二进制的机器码呢?这样岂不是运行更快?新 Java 虚拟机 GraalVM 中的 AOT 和 JIT 又有什么区别呢?