理解 perf.map

4
我知道一个很好的async_profiler工具,我用它来对我的生产项目进行性能分析。这里我想了解一下perf以及如何理解其输出。
我正在使用perf对堆栈跟踪进行采样。我使用以下选项运行JVM:-XX:+UnlockDiagnosticVMOptions -XX:+PreserveFramePointer -XX:+ShowHiddenFrames,以避免堆栈跟踪出现问题。
我使用命令sudo perf record -e cycles -g -p <my_pid>运行它,以便同时采样用户和内核堆栈跟踪,并比较结果百分比。这是我得到的结果: enter image description here start_thread符号对我来说似乎很清楚。它们来自于libjvm.so,我可以假设我运行了3个Worker线程来完成某些工作,这正是我在这里看到的。十六进制数字似乎是运行时编译的Java代码指令地址。 问题:但是perf-27405.map从哪里来的,为什么它出现在顶部?
1个回答

6

perf-<pid>.map文件是提供应用程序特定符号映射给perf的一种方式。

在您的案例中,其中一个采样指针0x00000000008e06e0属于libjvm.so - perf可以轻松显示这一点。但另一个采样指针0x00007f557d10c19f属于未由任何对象文件支持的匿名内存区域。这是动态生成的代码,除非有人提供帮助,否则perf无法对其进行任何解释。perf-<pid>.map文件是应用程序或外部工具提供动态生成代码符号信息的接口。

perf-map-agent就是Java的一个例子。它将perf-<pid>.map文件填充为JIT编译方法的信息,以便perf可以将这些地址映射到Java方法名称。


这意味着我的猜测是错误的。libjvm.so 下的所有指令指针实际上并不是我用 Java 编写的 JIT 方法,而是实际的运行时代码。 - St.Antario
问题是如何使所有的libjvm.so指令都带有可读性强的标签。我是否需要自己编译带有调试符号的JVM? - St.Antario
1
@St.Antario OpenJDK libjvm通常不包含调试符号。您可能需要安装单独的debuginfo软件包(https://dev59.com/Uajja4cB1Zd3GeqP7TVv#48253607)。 - apangin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接