1. -XX:+PrintCompilation 是什么
-XX:+PrintCompilation 是 HotSpot JVM 的一个 调试选项:
当 JVM 对方法进行 即时编译(JIT) 时,它会打印一条信息到控制台。
可以帮助我们了解:
哪些方法被编译了(热点方法)
哪些方法还在解释执行(Interpreter 模式)
JIT 编译器的优化顺序(C1 / C2 编译器)
输出示例
假设我们运行一个简单程序:
public class HotspotExample {
public static void main(String[] args) {
for (int i = 0; i < 1_000_000; i++) {
hotMethod();
}
}
private static void hotMethod() {
int x = 0;
for (int i = 0; i < 10; i++) {
x += i;
}
}
}
使用 JVM 启动参数:
java -XX:+PrintCompilation HotspotExample
可能输出(简化示例):
0 0 java.lang.Thread::sleep (5 bytes)
1 1 HotspotExample::main (15 bytes)
2 2 HotspotExample::hotMethod (42 bytes)
解释:
0,1,2 → 编译顺序编号
方法签名 → 被 JIT 编译的方法
字节大小 → 方法字节码大小
随着方法被多次调用,它会被 **热点探测器(C2 编译器)**编译优化成机器码。
2. 如何用它分析热点代码
启动 JVM 并打印编译信息
常用参数:
java -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining HotspotExample
-XX:+PrintInlining 可以显示 方法内联情况
-XX:+UnlockDiagnosticVMOptions 允许使用诊断参数
观察哪些方法频繁出现
热点方法:执行多次、循环内的函数
冷门方法:只被调用一次或几次,可能一直解释执行
注意:JIT 编译器通常需要一个 调用次数阈值 才会触发编译(默认 10,000 次左右,可用 -XX:CompileThreshold=xxx 调整)。
结合 -XX:+PrintAssembly(可选)
如果你想看到机器码,可以加上:
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly HotspotExample
需要安装 hsdis 插件(HotSpot Disassembler)
可以直接看到 JIT 生成的汇编代码
3. 实战分析示例
假设我们有一个 StringConcat 的性能测试:
public class HotMethodTest {
public static void main(String[] args) {
for (int i = 0; i < 10_000_000; i++) {
concatString();
}
}
public static String concatString() {
String s = "Hello";
for (int i = 0; i < 10; i++) {
s += "World";
}
return s;
}
}
启动:
java -XX:+PrintCompilation HotMethodTest
输出可能类似:
0 0 HotMethodTest::main
1 1 HotMethodTest::concatString
2 2 java.lang.String::concat
分析:
concatString 被识别为热点方法 → JIT 编译
java.lang.String::concat 也被编译 → JVM 优化内部方法
可以发现循环内的性能瓶颈所在(这里就是字符串多次连接,JIT 会尝试优化,但性能仍比 StringBuilder 差)
4. 小技巧
降低阈值(快速看到编译):
-XX:CompileThreshold=1000
区分 C1 / C2 编译器:
-XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation
结合 JITWatch:
-XX:+LogCompilation 会生成日志文件
可以用 JITWatch
可视化
能看到每个方法 字节码 → 优化 → 汇编代码
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70050070/viewspace-3117517/ ,如需转载,请注明出处,否则将追究法律责任。