【问题标题】:Does filtering classes for cpu profiling work in Java VisualVM?用于 cpu 分析的过滤类在 Java VisualVM 中是否有效?
【发布时间】:2011-11-04 13:23:49
【问题描述】:

我想在 Java VisualVm(版本 1.7.0 b110325)中过滤哪些类被 cpu-profiled。为此,我尝试在 Profiler -> Settings -> CPU-Settings 下将“Profile only classes”设置为我的测试包,但没有效果。然后我尝试通过将所有 java.* 和 sun.* 类设置在“Do not profile classes”中来摆脱它们,这也没有效果。

这只是一个错误吗?还是我错过了什么?有解决方法吗?我的意思是:

我想这样做主要是为了获得每个方法消耗的 CPU 的一半正确百分比。为此,我需要摆脱烦人的测量,例如对于sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run()(大约 70%)。许多用户似乎有这个问题,参见例如

【问题讨论】:

  • 您的目的是让代码尽可能快地运行吗?或者只是为了得到一些百分比,不管它们是什么意思?常用的“时间”是高度模糊的。
  • 是的,我的主要目标是让代码运行得更快。我还想估计代码应该更改多少。因此,我想大致了解所有热点及其严重程度。我认为 VisualVm 的结果是可以接受的,尽管使用了挂时间 - 如果只有少数 sun.* 和 java.* 类不会弄乱所有统计数据。

标签: java profiling profiler visualvm jvisualvm


【解决方案1】:

您在配置文件中看到sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run() 的原因是您未选中Profile new Runnables 选项。

此外,如果您对分析会话进行快照,您将能够看到任何热点方法的整个调用堆栈 - 这样您就可以从 run() 方法导航到您自己的应用程序逻辑方法,过滤掉Profile new Runnables 选项产生的噪音。

【讨论】:

  • 感谢 JB (+5),我将在星期一检查该选项 - 听起来像是解决方案 :) 我确实拍了一张快照,这给了我调用树视图,这不好,因为只有Profiler 视图为我提供了每种方法消耗的 CPU 百分比。由于递归,我的调用堆栈过于复杂,无法从中获取合理的性能信息。
  • 感谢 JB,禁用“Profile new Runnables”选项成功了。
  • 请注意禁用上述选项的后果。启用该选项后,您将自动获得有关所有新启动的线程/可运行文件的信息。关闭该选项后,您必须确保提供详尽的根方法列表。
【解决方案2】:

好的,既然您的目标是让代码尽可能快地运行,那么让我来建议如何做到这一点。 我不是 VisualVM 方面的专家,但我可以告诉你什么是有效的。 (实际上只有少数分析器会告诉您您需要知道的内容,即 - 堆栈中的哪些代码行是挂钟时间的正常部分。)

我唯一关心的测量是总时间的一些秒表,或者,如果代码有类似帧速率的东西,每秒的帧数。我不需要任何进一步的精确细分,因为当有一种非常直接的方法可以找到它时,它充其量只是一个遥远的线索,说明什么是在浪费时间(而且通常是完全不相关的)。

如果你不想做random-pausing,这取决于你,但它已被证明有效,here's an example of a 43x speedup

基本上,这个想法是您获得(少量,例如 10 个)堆栈样本,这些样本是在随机挂钟时间获取的。 每个样本(显然)由一个呼叫站点列表组成,最后可能还有一个非呼叫站点。 (如果样本在 I/O 或睡眠期间,它将在系统调用中结束,这很好。这就是你想知道的。)

如果有一种方法可以加快您的代码速度(几乎肯定有),您会将其视为至少出现在一个堆栈示例中的一行代码。 它出现在任何一个样本上的概率与它使用的时间分数完全相同。 因此,如果有一个调用站点或其他代码行使用了正常的一小部分时间,并且您可以避免执行它,那么总时间将减少该部分。

我不认识每一个分析器,但我认识的一个可以告诉你Zoom。 其他人也许能够做到。 它们可能更漂亮,但当您的目的是最大限度地提高性能时,它们不会比手动方法更快或更好。

【讨论】:

  • 请注意,在 JVM 中,即使执行非常频繁,方法也可能永远不会出现在堆栈跟踪中。这样做的原因是 JVM 允许获取堆栈跟踪的方式 - 线程的堆栈跟踪只能在检查点上获取,而检查点可能不会被 JIT 插入到每个方法中。
  • 你是“随机暂停传教士”,迈克 :) 无论如何感谢您的回复,如果我没有给你一个链接来描述该技术,我会赞成它。我确实尝试过,但由于递归,调用堆栈非常复杂。配置文件视图将其分解为具有运行时间百分比的方法,因此热点更容易看到。其次,配置文件视图显示所有热点及其严重程度。这很好地概述了必须进行哪些调整以及调整多少。你同意吗?
  • @DaveBall:这与热点和测量无关。是的,调用堆栈很复杂,并且存在递归。即便如此,看看您是否可以全部选择并复制到编辑器中。然后研究一下,看看你能不能回答简单的问题“当时在做什么,为什么在做?”然后再做几次。这会告诉你它为什么要花时间,它会告诉你应该专注于什么。不要被递归或复杂的堆栈吓倒。您在 3 个样本中的 2 个样本上看到的任何代码行平均花费您 (2+1)/(3+2)=60%。很好的狩猎。
  • @DaveBall:堆栈越深,狩猎越好。既然你提到了递归,我敢打赌这是花费时间的原因。以我的经验,通知失控是导致性能问题的主要原因之一。 (顺便说一句:热点(PC 集中的地方)在像你这样的真实代码中几乎不重要。另外,如果你看到一个高包容性的函数,你会去看看它 - 错了!寻找它被调用的原因。分析器不不会告诉你的。堆栈样本会。)
  • @DaveBall:很抱歉继续。 (我讨厌“传道者”。)你拿了 1 个样本,看到了很多递归。 Rule of Succession 表示,平均而言,当这种情况发生时,递归将花费您 (1+1)/(1+2)=67%。所以很有可能你已经发现了问题。
猜你喜欢
  • 2011-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-12
  • 1970-01-01
  • 1970-01-01
  • 2011-07-20
相关资源
最近更新 更多