我是靠谱客的博主 善良月光,最近开发中收集的这篇文章主要介绍十、如何使用perf工具分析java程序,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

问题 1: 使用 perf 工具时,看到的是 16 进制地址而不是函数名

在 CentOS 系统中,使用 perf 工具看不到函数名,只能看到一些 16 进制格式的函数地址

# 只要你观察一下 perf 界面最下面的那一行,就会发现一个警告信息:
Failed to open /opt/bitnami/php/lib/php/extensions/opcache.so, continuing without symbols
  • 针对这种情况,我总结了下面四个解决方法
  1. 在容器外面构建相同路径的依赖库.原理上可行,但是并不推荐,一方面是因为找出这些依赖库比较麻烦,更重要的是,构建这些路径,会污染容器主机的环境。
  2. 在容器内部运行 perf.这需要容器运行在特权模式下,但实际的应用程序往往只以普通容器的方式运行。所以,容器内部一般没有权限执行 perf 分析。比方说,如果你在普通容器内部运行 perf record ,你将会看到下面这个错误提示:
    $ perf_4.9 record -a -g
    perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error 1 (Operation not permitted)
    perf_event_open(..., 0) failed unexpectedly with error 1 (Operation not permitted)
    

当然,其实你还可以通过配置 /proc/sys/kernel/perf_event_paranoid (比如改成 -1),来允许非特权用户执行 perf 事件分析。不过为了安全起见,这种方法也不推荐。

  1. 指定符号路径为容器文件系统的路径
    $ mkdir /tmp/foo
    $ PID=$(docker inspect --format {{.State.Pid}} phpfpm)
    $ bindfs /proc/$PID/root /tmp/foo
    $ perf report --symfs /tmp/foo
    
    # 使用完成后不要忘记解除绑定
    $ umount /tmp/foo/
    
  2. 在容器外面把分析纪录保存下来,再去容器里查看结
    $ perf record -g -p < pid>   # 宿主机采样
    $ docker cp perf.data phpfpm:/tmp 
    $ docker exec -i -t phpfpm bash #进入虚拟机
    $ cd /tmp/ 
    $ apt-get update && apt-get install -y linux-tools linux-perf procps
    $ perf_4.9 report   #虚拟机中分析
    
  • ubuntu安装perf
    $ apt-get install -y linux-tools-common linux-tools-generic linux-tools-$(uname -r))
    
  • Debian
    $ apt-get install -y linux-perf
    

问题 2:如何用 perf 工具分析 Java 程序

从系统层面你只能看到 JVM 的函数堆栈,而不能直接得到 Java 应用程序的堆栈

perf_events 实际上已经支持了 JIT,但还需要一个 /tmp/perf-PID.map 文件,来进行符号翻译。当然,开源项目 perf-map-agent 可以帮你生成这个符号表
此外,为了生成全部调用栈,你还需要开启 JDK 的选项 -XX:+PreserveFramePointer.还可以参考Netflix 的技术博客,来查看详细的使用步骤。

问题 3:为什么 perf 的报告中,很多符号都不显示调用栈

通过man可以看到,-g 选项等同于 –call-graph,它的参数是后面那些被逗号隔开的选项,意思分别是输出类型、最小阈值、输出限制、排序方法、排序关键词、分支以及值的类型。其中 threshold 的默认值为 0.5%,也就是说,事件比例超过 0.5% 时,调用栈才能被显示.

这种情况下,你只需要给 perf report 设置一个小于 0.34% 的阈值,就可以显示我们想看到的调用图了。比如执行下面的命令:

$ perf report -g graph,0.3

问题 4:怎么理解 perf report 报告中 Children 和 Self 的含义

关于 Children 和 Self 的含义,手册里其实有详细说明,还很友好地举了一个例子,来说明它们的百分比的计算方法。简单来说:

  1. Self 是最后一列的符号(可以理解为函数)本身所占比例;
  2. Children 是这个符号调用的其他符号(可以理解为子函数,包括直接和间接调用)占用的比例之和。
  3. perf 这种动态追踪工具,会给系统带来一定的性能损失。
  4. vmstat、pidstat 这些直接读取 proc 文件系统来获取指标的工具,不会带来性能损失。
 

最后

以上就是善良月光为你收集整理的十、如何使用perf工具分析java程序的全部内容,希望文章能够帮你解决十、如何使用perf工具分析java程序所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部