如果你有一个Java应用程序,当它不做任何事情时消耗CPU,你如何确定它在做什么?

2022-09-03 04:43:14

我正在调用供应商的Java API,在某些服务器上,JVM似乎在登录到API后进入低优先级轮询循环(CPU使用率为100%)。其他服务器上的同一应用不会表现出此行为。这发生在WebSphere和Tomcat上。环境设置起来很棘手,所以很难尝试在 Eclipse 中做一些类似性能分析的事情。

有没有办法分析(或其他一些检查方法)在Tomcat中运行的现有Java应用程序,以找出当它处于这种旋转等待状态时正在执行的方法?应用在进入此状态时仅执行一个方法(供应商的方法)。供应商无法复制该行为(当然)。


更新:

使用JConsole,我能够确定谁在跑步以及他们在做什么。我花了几个小时才弄清楚它为什么要这样做。最终的问题是,供应商正在使用的 API jar 与它正在使用的数据库配置不完全匹配。它默认在配置中具有轻微不匹配的服务器上启用跟踪和性能监视。我用了一个不同的罐子,一切都很好。

所以,谢谢约书亚,谢谢你的回答。JConsole非常易于设置和使用来监视现有应用程序。

@Cringe - 我对你建议的一些选项进行了一些实验。我在设置JProfiler时遇到了一些问题,它看起来不错(但价格昂贵)。展望未来,我继续添加Eclipse Profiler插件,我将查看不同的开源分析器以比较功能。


答案 1

如果您使用的是 Java 5 或更高版本,则可以使用 jconsole 连接到应用程序以查看所有正在运行的线程。jstack也会做一个堆栈转储。我认为这即使在像Tomcat这样的容器中也应该有效。

这两个工具都包含在JDK5及更高版本中(我假设该过程至少需要是Java 5,尽管我可能是错的)

更新:同样值得注意的是,从JDK 1.6更新7开始,现在有一个名为VisualVM的捆绑分析器,可以使用“jvisualvm”启动。它看起来像是一个 java.net 项目,因此该页面可能会提供其他信息。我还没有使用过这个,但它对于更严肃的分析似乎很有用。

希望有所帮助


答案 2

面对同样的问题,我使用了YourKit分析器。除非您实际连接到它,否则它的加载程序不会激活(尽管它确实打开了一个端口来侦听连接)。分析器本身有一个很好的“获取在每种方法上花费的时间量”,同时在不那么突兀的模式下工作。

另一种方法是在具有最高优先级的“看门狗”线程中检测CPU负载(通过JNI,因此您需要一个外部库),并在CPU足够高足够长的时间时开始记录所有线程。您可能会发现这篇文章很有启发性。


推荐