如何排查Java单元测试中C2Compiler::compile_method编译的具体方法?
定位C2编译的具体方法:针对单元测试的排查方案
通过JVM编译日志直接输出
启动单元测试时添加JVM参数,打印C2编译的详细信息:- 基础编译日志:
-XX:+PrintCompilation,会输出被编译方法的全限定名、编译级别(C2对应level 4)、编译耗时等核心信息。 - 更详细的编译细节:
-XX:+PrintCompilationDetails或-XX:+PrintCompilationTimings,前者输出编译过程的阶段耗时,后者统计每个方法的编译总耗时,方便快速定位耗时最长的编译目标。
- 基础编译日志:
用AsyncProfiler生成带编译事件的火焰图/统计报告
既然你已经在用火焰图分析,直接用AsyncProfiler跟踪compiler.compile.method事件:- 命令示例:
./profiler.sh -d <测试运行时长> -e compiler.compile.method -o txt,flamegraph <测试进程PID> - 生成的txt报告里会按编译耗时排序列出所有被C2编译的方法,火焰图也会直观展示每个方法编译环节的时间占比,和你已有的火焰图形成互补。
- 命令示例:
用jcmd工具实时查询编译信息
单元测试运行过程中,用JDK自带的jcmd工具获取编译相关数据:- 查看当前已编译的方法列表:
jcmd <PID> Compiler.print_compilation - 查看编译统计(含每个方法的编译次数、耗时):
jcmd <PID> Compiler.statistics - 还可以通过自定义指令文件开启更细粒度的跟踪:创建
directives.json文件,内容如下,然后执行jcmd <PID> Compiler.directives_add file=directives.json,就能记录指定或所有方法的编译细节:{ "match": "*", "exclude": "java.*", "printCompilation": true, "logCompilation": "/tmp/compile.log" }
- 查看当前已编译的方法列表:
内容的提问来源于stack exchange,提问作者emitrax
相关产品推荐
相关产品推荐

