我在ubuntu 12.04上使用perf工具来分析hadoop 2.4.1 map/reduce作业的系统级性能:
perf record -ag -F 100 sleep 60
我的目标是确定哪些进程/例程正在使用cpu并确定优化候选者.
内核符号被正确解码,但java代码不是.Perf报告看起来像:
Samples: 39K of event 'cycles', Event count (approx.): 11326629675790000f9f0 â + 10.64% java perf-9201.map [.] 0x00007eff6c188127 + 10.57% java perf-8988.map [.] 0x00007f71ac7b9a29 + 9.91% java perf-9077.map [.] 0x00007fa9e92073e0 + 9.77% java perf-9025.map [.] 0x00007f849cdf41a9 + 9.26% java perf-8747.map [.] 0x00007f078c6bda82 + 7.85% java perf-31343.map [.] 0x00007f6671041cb4 + 5.81% java perf-8835.map [.] 0x00007f5df0d5afc4 + 5.78% java liblzo2.so.2.0.0 [.] lzo1x_decompress + 2.61% java [kernel.kallsyms] [k] copy_user_generic_string + 1.58% java libc-2.15.so [.] 0x000000000008ce40 + 0.93% java perf-9677.map [.] 0x00007f7c81012887 + 0.86% swapper [kernel.kallsyms] [k] intel_idle + 0.69% java libjvm.so [.] SpinPause
所以问题是,我如何获得perf来解码java代码的符号?
事实证明,perf输出中显示的perf- $ pid.map对象与JIT编译的java代码相关联.为了使perf能够解码这些符号,java代码需要生成/tmp/perf-$pid.map符号映射文件.
github上有一个perf-map-agent库,可用于为JITed代码生成符号映射文件.在库就位后,将-agentpath:<dir> /libperfmap.so添加到java命令行.
要使hadoop作业生成符号映射,请将以下行添加到hadoop-env.sh:
export HADOOP_JAVA_PLATFORM_OPTS="-agentpath:/usr/lib/oprofile/libjvmti_oprofile.so $HADOOP_JAVA_PLATFORM_OPTS" export JAVA_TOOL_OPTIONS="-agentpath:/usr/lib/libperfmap.so $JAVA_TOOL_OPTIONS"