在命令行中分析正在运行的 Java 应用程序
Posted
技术标签:
【中文标题】在命令行中分析正在运行的 Java 应用程序【英文标题】:Profiling a running Java application in command line 【发布时间】:2011-10-14 08:00:58 【问题描述】:我经常使用 VisualVM 分析运行 Java 应用程序,但它需要 X 才能在机器上运行。
我知道我可以通过管理端口进行连接,但这将是一个离线采样分析,这对我来说还不够。
所以我正在寻找一种解决方案,通过它我可以从命令行分析正在运行的 Java 应用程序的方法的 CPU 使用率。我在服务器上收集数据就足够了,然后可以在不同的机器上分析收集到的数据。
更新:
看来我需要更具体一些。我想从命令行分析一个正在运行的 Java 应用程序,我不想停止它并重新运行它。
【问题讨论】:
你能用 jstack 收集 10 或 20 个堆栈样本吗?那么如果 Foo 是一个方法,它的总时间使用是包含它的样本的一部分。它的 CPU 使用率是那些不以 I/O 或系统调用终止的样本的一部分。它的“自身时间”是它本身是终点的样本的一部分。 这和 VisualVM 离线分析是一样的,不是吗? Check the doc. 它不会按行(不是函数)告诉您该行负责的包含时间(非独占)百分比,以及总时间(不仅仅是 CPU)。它受到these problems 的影响。堆栈采样并不漂亮,但它很快就发现了性能问题。其他工具很漂亮,它们会给你很多数字来解决问题,但它们并不能直接带你解决问题,不管它是什么。 我试图获取堆栈跟踪,但它拒绝在没有-F
标志的情况下运行,它会冻结我的应用程序。
嘿,我不需要漂亮的东西。我要么在 IDE 下运行它并以这种方式收集它们,要么使用 jstack 之类的东西来快照正在运行的应用程序的堆栈。
【参考方案1】:
我们在服务器上使用了hprof,如果您无法运行完整的 VisualVM 会话,它肯定比 sysouts 更好。
使用 hprof 的例子很多:
http://www.javalobby.org/java/forums/t19612.html https://coderwall.com/p/il3h4g/easy-profiling-java-from-command-line http://www.brendangregg.com/blog/2014-06-09/java-cpu-sampling-using-hprof.html【讨论】:
但我真的不明白如何将它附加到 pid 抱歉,AFAIK,hprof
不允许附加到进程。你最好的选择是研究像 jprofile 和 jtop 这样的工具。 java.sun.com/developer/technicalArticles/J2SE/monitoring
@SanjayT.Sharma 我正在使用 HPROF 通过使用 cpu=times 进行 CPU 分析,并在每次特定运行应用程序后生成数据,但我无法分析数据,例如哪个进程一个特定的运行有最大 cpu 使用率。使用 jhat 并没有多大帮助,请启发。
@blong:好地方,修复了损坏的链接。
@SanjayT.Sharma ,太好了,非常感谢! Downvote 转换为 upvote :)【参考方案2】:
您可以远程运行大多数商业分析器,以便在服务器上运行代理,然后通过您的开发机器上的客户端连接到该代理。我最喜欢的分析器是 JProfiler。这是相当合理的购买,而且非常稳定(并非所有商业分析器都是如此)。
http://www.ej-technologies.com/products/jprofiler/overview.html
YourKIT 是其他稳定但不是我最喜欢的商业分析器。
http://www.yourkit.com/
那些较小的供应商制造了很好的工具。这些工具将为您提供有关方法计时、内存使用、GC 等的大量信息。比 jconsole 更多。
【讨论】:
【参考方案3】:你能用 jstack 收集 10 或 20 个堆栈样本吗?那么如果 Foo 是一个方法,它的总时间使用是包含它的样本的一部分。它的 CPU 使用率是那些不以 I/O 或系统调用终止的样本的一部分。它的“自身时间”是它自己作为终点的样本的分数。
我不需要任何漂亮的东西。我要么在 IDE 下运行它并以这种方式收集它们,要么使用像 jstack 这样的东西来快照正在运行的应用程序的堆栈。
这就是random-pause 技术。
【讨论】:
我选择了这个想法:svn.apache.org/repos/asf/jackrabbit/sandbox/jackrabbit-j3/src/… 这个解决方案帮助我找到了服务器上 DNS 解析的瓶颈。再次感谢您! @KARASZI István:很高兴它有帮助。【参考方案4】:看起来从命令行分析 java 应用程序的“内置”方法是使用分析命令行参数启动它,像这样
$ java -Xrunhprof:cpu=samples,file=myprogram.hprof ...
然后在进程退出后(此时文件已创建),使用一些 GUI 工具(或 Web 服务器工具,如 jhat)或 command line tool 检查文件“myprogram.hprof”。
如果您使用https://***.com/a/2344436/32453 提到的“QUIT”信号技巧,那么您可以在不退出 JVM 的情况下随意生成文件(它似乎附加到前一个输出文件)。或者等到进程退出再生成文件。
此(内置)分析器不经常进行采样,因此总体上通常会降低减速/影响。
参考:http://web.archive.org/web/20160623224137/https://thunderguy.com/semicolon/2004/04/18/profiling-a-java-program-easily/
您也可以通过收集大量 jstack 并将它们转储到 ex: flamegraph 或其他一些分析器/聚合器中来执行“穷人的分析器”...
【讨论】:
感谢指点!给未来读者的注意事项:hprof 是在 Java RUNNABLE 状态下对线程进行采样(所以它不等同于聚合多个jstack
转储,就像我预期的那样,但它也不测量 CPU 消耗)。它还有其他问题 - 请参阅 brendangregg.com/blog/2014-06-09/…【参考方案5】:
jvmtop 应用程序是从命令行进行分析的便捷工具。无需停止 jvm。用法:
jvmtop.sh --profile <PID>
会给你这样的输出,当应用运行时会更新:
Profiling PID 24015: org.apache.catalina.startup.Bootstrap
36.16% ( 57.57s) hudson.model.AbstractBuild.calcChangeSet()
30.36% ( 48.33s) hudson.scm.SubversionChangeLogParser.parse()
7.14% ( 11.37s) org.kohsuke.stapler.jelly.JellyClassTearOff.parseScript()
...
优点是它不使用仪器。待分析的 jvm 的类不会被改变。
如果您正在寻找更直观的东西,请查看基于 jvmtop 的 jvm-mon
【讨论】:
多年来我一直在搞乱和诅咒visualvm。感谢您向我指出这个方便的工具。无需 JVM 代理、服务器重启等即可工作。只需解压您要分析的框,将 JAVA_HOME 指向正确的位置并运行。 这是一个很棒的工具,但是这个项目看起来已经死了。自 2015 年以来没有发布 jvm-mon 是一个......次优工具,分析应该也意味着堆栈跟踪。 自 JDK 9 以来 jvmtop 似乎不再工作了。【参考方案6】:分析“已启动”JVM 的一种方法是聚合多个 jstacks。
例如,您可以将它们解析并显示为 FlameGraph(请参阅该链接的各种答案中的详细信息,我不会在此处重复包含它们)。
【讨论】:
【参考方案7】:使用https://github.com/jvm-profiling-tools/async-profiler 可以实现最精确的分析。
这个项目是一个低开销的 Java 采样分析器,不会受到安全点偏差问题的影响。它具有特定于 HotSpot 的 API 来收集堆栈跟踪和跟踪内存分配。该分析器适用于 OpenJDK、Oracle JDK 和其他基于 HotSpot JVM 的 Java 运行时。
这是我从命令行安装和运行它的脚本:
async-profiler.sh
if [ ! -d profiler ]; then
mkdir profiler && cd profiler && curl -L https://github.com/jvm-profiling-tools/async-profiler/releases/download/v1.6-ea/async-profiler-1.6-ea-linux-x64.tar.gz | tar xvz
echo 1 > /proc/sys/kernel/perf_event_paranoid
echo 0 > /proc/sys/kernel/kptr_restrict
#apt install openjdk-8-dbg
else
cd profiler
fi
#jps
./profiler.sh -d 60 -f dump_`date +%Y-%m-%d_%H-%M-%S`.jfr `jps -q`
假设应用程序在同一用户下运行,并且 jps 列出了一个 java 进程 PID。 分析持续时间为 60 秒。
无需修改应用的启动选项或重新启动应用。
用于检查转储的 GUI 内置在 IntelliJ IDEA Ultimate 中:https://www.jetbrains.com/help/idea/cpu-profiler.html。
【讨论】:
关于 async-profiler 的精美插图文章:hackernoon.com/…以上是关于在命令行中分析正在运行的 Java 应用程序的主要内容,如果未能解决你的问题,请参考以下文章
在 Eclipse 中分析 Java 应用程序的最佳方法是啥?