Centos7 perf、FlameGraph、perf-map-agent安装使用

perf

安装(需要安装perl)

yum install perf

使用

perf top -p 进程号

但是这样看起来比较难受,没有图表,因此有人发明了火焰图,便于分析进程占用的CPU,见下文

FlameGraph

下载源码(无须安装,建议创建软链接)

https://github.com/brendangregg/FlameGraph

使用方法

# 进程号是pid,秒数是采集时间
perf record -F 99 -p 进程号 -g -- sleep 秒数
# 下面这个命令可以直接查看采集的数据,但是不友好
# perf report -n --stdio
# 生成perf文件
perf script > out.perf
# 生成folded文件 (pl文件在上面下载的FlameGraph根目录下)
FlameGraph-master/stackcollapse-perf.pl out.perf > out.folded
# 生成svg文件,也就是火焰图文件 (建议使用chrome打开,ie打开有问题,ctrl + f 可以正则搜索)
FlameGraph-master/flamegraph.pl out.folded > kernel.svg

如果想监控java,需要再安装一套东西 ,见下文

perf-map-agent

下载地址

GitHub - jvm-profiling-tools/perf-map-agent: A java agent to generate method mappings to use with the linux `perf` tool

安装(需要java环境)

# 安装环境,需要先安装gcc-c++,以及cmake,yum就能安装
yum install gcc-c++
yum install cmake
# yum install java-1.8.0-openjdk
yum install java-1.8.0-openjdk-devel
# java_home根据实际情况配置
export JAVA_HOME=/usr/lib/jvm/java-openjdk/

# 安装perf-map-agent
cmake .
make
# 创建软链接(但是不全)
bin/create-links-in /usr/local/bin

可选安装 dtrace

Oracle Linux 7 (x86_64) UEK Release 6 | Oracle, Software. Hardware. Complete.

下载 dtrace-2.0.0-1.9.1.el7.x86_64 和 libdtrace-ctf-1.1.0-2.el7.x86_64 的rpm并安装

配置FlameGraph目录(不配置无法使用perf-java-flame)

export FLAMEGRAPH_DIR=/root/FlameGraph-master

永久配置需要写入 ~/.bashrc

不配置可能报错

FlameGraph executable not found at '/stackcollapse-perf.pl'. Please set FLAMEGRAPH_DIR to the root of the clone of https://github.com/brendangregg/FlameGraph.

 使用perf-map-agent (火焰图方法,其他方法可以百度)

# !!!! 被监控进程需要加入java启动参数 -XX:+PreserveFramePointer   不然啥也看不见
# 默认收集15秒,如果要修改默认收集时间,参考下面注释
# export PERF_RECORD_SECONDS=60
perf-java-flames 进程号

使用中可能遇到的错误:

没安装java可能会报错(实际上是没安装javah,即java-1.8.0-openjdk-devel)

-- Could NOT find JNI (missing:  JAVA_INCLUDE_PATH JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH)
CMake Error at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:108 (message):
  Could NOT find Java (missing: Java_JAR_EXECUTABLE Java_JAVAC_EXECUTABLE
  Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE) (found version "1.8.0.322")
Call Stack (most recent call first):
  /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:315 (_FPHSA_FAILURE_MESSAGE)
  /usr/share/cmake/Modules/FindJava.cmake:191 (find_package_handle_standard_args)
  CMakeLists.txt:23 (find_package)

其实关键是这句 (missing: Java_JAR_EXECUTABLE Java_JAVAC_EXECUTABLE
  Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE) ,找不到javac,javah等,只要指定了JAVA_HOME即可(前提装了java)

export JAVA_HOME=/usr/lib/jvm/java-openjdk/
# 前提是这个java_home的bin目录下有javah,javac等应用程序

没指定java_home还可能报错(没有tools.jar)

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/tools/attach/AgentInitializationException
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
        at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
        at java.lang.Class.getMethod0(Class.java:3018)
        at java.lang.Class.getMethod(Class.java:1784)
        at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:650)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:632)
Caused by: java.lang.ClassNotFoundException: com.sun.tools.attach.AgentInitializationException
        at java.net.URLClassLoader.findClass(URLClassLoader.java:387)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
        ... 7 more

我看有人用指定tools.jar解决,一般来说指定java_home就能解决,如果还没解决,看看是不是权限不对

-Xbootclasspath/a:/usr/lib/jvm/java-openjdk/lib/tools.jar

cmake可能报错

-- Could NOT find JNI (missing:  JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY)
-- Configuring done
-- Generating done
-- Build files have been written to: /root/perf-map-agent-master

我还以为是java_home配置错了,结果是因为我的java_home里的jre文件夹名称不对,我的jre文件夹的名称叫做jre1.8.0_151,而实际上cmake只认识jre这个名称,我把jre1.8.0_151改名jre成功解决

如果报错这个

ERROR: No stack counts found

可能是java程序没跑什么东西,拿不到样本

cmake安装有问题可能报错(gcc没装好)

-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /bin/cc
-- Check for working C compiler: /bin/cc -- broken
CMake Error at /usr/share/cmake/Modules/CMakeTestCCompiler.cmake:61 (message):
  The C compiler "/bin/cc" is not able to compile a simple test program.

  It fails with the following output:

   Change Dir: /root/perf-map-agent-master/CMakeFiles/CMakeTmp



  Run Build Command:/bin/gmake "cmTryCompileExec1466212255/fast"

  /bin/gmake -f CMakeFiles/cmTryCompileExec1466212255.dir/build.make
  CMakeFiles/cmTryCompileExec1466212255.dir/build

  gmake[1]: Entering directory
  `/root/perf-map-agent-master/CMakeFiles/CMakeTmp'

  /usr/bin/cmake -E cmake_progress_report
  /root/perf-map-agent-master/CMakeFiles/CMakeTmp/CMakeFiles 1

  Building C object
  CMakeFiles/cmTryCompileExec1466212255.dir/testCCompiler.c.o

  /bin/cc -o CMakeFiles/cmTryCompileExec1466212255.dir/testCCompiler.c.o -c
  /root/perf-map-agent-master/CMakeFiles/CMakeTmp/testCCompiler.c

  Linking C executable cmTryCompileExec1466212255

  /usr/bin/cmake -E cmake_link_script
  CMakeFiles/cmTryCompileExec1466212255.dir/link.txt --verbose=1

  /bin/cc CMakeFiles/cmTryCompileExec1466212255.dir/testCCompiler.c.o -o
  cmTryCompileExec1466212255 -rdynamic

  collect2: fatal error: cannot find 'ld'

  compilation terminated.

  gmake[1]: Leaving directory
  `/root/perf-map-agent-master/CMakeFiles/CMakeTmp'

  gmake[1]: *** [cmTryCompileExec1466212255] Error 1

  gmake: *** [cmTryCompileExec1466212255/fast] Error 2





  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)


-- Configuring incomplete, errors occurred!
See also "/root/perf-map-agent-master/CMakeFiles/CMakeOutput.log".
See also "/root/perf-map-agent-master/CMakeFiles/CMakeError.log".

上述问题我使用gcc随便编译代码也报错

# gcc -o a.out a.c
collect2: fatal error: cannot find 'ld'
compilation terminated.

 于是使用下面方法解决

yum update binutils

 

perf-java-flames 运行可能报错

Exception in thread "main" java.lang.UnsatisfiedLinkError: no attach in java.library.path
        at java.lang.ClassLoader.loadLibrary(Unknown Source)
        at java.lang.Runtime.loadLibrary0(Unknown Source)
        at java.lang.System.loadLibrary(Unknown Source)
        at sun.tools.attach.LinuxVirtualMachine.<clinit>(LinuxVirtualMachine.java:342)
        at sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(LinuxAttachProvider.java:63)
        at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:208)
        at net.virtualvoid.perf.AttachOnce.loadAgent(AttachOnce.java:38)
        at net.virtualvoid.perf.AttachOnce.main(AttachOnce.java:34)

说明jdk的版本和tools.jar不匹配

perf-java-flames 运行可能报错

Couldn't record kernel reference relocation symbol
Symbol resolution may be skewed if relocation was used (e.g. kexec).
Check /proc/kallsyms permission or run as root.

解决办法

echo 0 > /proc/sys/kernel/kptr_restrict
cat /proc/sys/kernel/kptr_restrict

perf-java-flames 运行可能报错

Error: Could not find or load main class net.virtualvoid.perf.AttachOnce

解决办法

# 然后检查所起的java程序的用户,有没有perf-map-agent和FlameGraph目录的权限(我Tomcat起的java程序,然后那两个目录被我放在了root下)
chmod -R 777 /root/

还可能报错(未解决,我换了其他java程序是正常跑的,这个不知道为什么)

Exception in thread "main" com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file: target process not responding or HotSpot VM not loaded
        at sun.tools.attach.LinuxVirtualMachine.<init>(LinuxVirtualMachine.java:106)
        at sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(LinuxAttachProvider.java:63)
        at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:208)
        at net.virtualvoid.perf.AttachOnce.loadAgent(AttachOnce.java:38)
        at net.virtualvoid.perf.AttachOnce.main(AttachOnce.java:34)

说说自己对火焰图的理解

x轴:CPU占用时间,非时间顺序轴

y轴:堆栈调用深度

上图我是拿excl表格生成的,从上图看e函数和d函数吃CPU的时间最长,剩下时间被f函数和c函数吃完,a函数和b函数只是当了跳板,并未实际吃到CPU,真正的CPU时间应该被其上面的函数吃完

更多文档参考

Perf分析CPU性能问题笔记 - 云+社区 - 腾讯云

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值