为什么在VisualVM分析器中没有显示所有方法?

10

我正在使用 VisualVM 来查看我的应用程序何处运行缓慢。但它并未显示所有方法,可能是因为没有显示导致应用延迟的所有方法。

我有一个实时应用程序(声音处理),并且存在几百微秒的时间不足。

VisualVM 是否会隐藏那些本身很快的方法?

更新 1

通过抽样和猜测,我找到了一个缓慢的方法。这是一个被关闭调试日志记录中调用的 toString() 方法,但它却消耗了时间。

设置 帮助我解决了问题,并且现在我知道了如何查看它:这取决于 从哪里开始分析 选项。


你正在使用采样器还是分析器?采样器会在定义的时间间隔内进行采样。分析器更加准确,但速度较慢。 - Mattias Isegran Bergander
调试日志应该全部包含 if (log.isDebugEnabled()) { 或类似的语句,以避免在日志调用中进行字符串连接和其他操作。 - Mattias Isegran Bergander
请参阅 https://blogs.oracle.com/nbprofiler/entry/profiling_with_visualvm_part_1 和 https://blogs.oracle.com/nbprofiler/entry/profiling_with_visualvm_part_2 以获取有关性能分析和如何设置性能分析根和仪器过滤器的更多信息。 - Tomas Hurka
3个回答

15
除了Ryan Stewart提到的过滤器之外,以下是一些方法不出现在性能分析器中的额外原因:
  • 采样分析本质上是随机的:每隔N毫秒就会取一个所有线程当前堆栈的样本。一些实际执行但在你运行期间未被任何样本捕获的方法将不会出现。这通常不是太大的问题,因为它们没有在任何样本中出现的事实意味着极有可能这些方法不会占用你运行时的大部分时间。
  • 在visualvm中使用基于仪器的采样(称为"CPU profiling")时,您需要定义受监视方法的入口点("Start profiling from"选项)。我发现这对于默认包中的方法会失败,并且也不会获取在连接分析器时正在运行的方法的时间(在当前调用期间 - 它将在后续调用中获取)。这可能是因为直到当前调用完成后,仪器化的方法才会被换入。
  • 采样受基于堆栈跟踪的分析的潜在严重问题的影响,即在代码的安全点处只会采样。当请求跟踪时,每个线程都会被强制到安全点,然后才会采集堆栈。在某些情况下,您的代码可能存在一个热点,它不进行安全点轮询(对于JIT可以保证在固定迭代次数后终止的简单循环很常见),与一些具有安全点轮询的代码交错执行。您的堆栈将始终显示您的进程处于安全点代码中,而不是在无安全点的代码中,即使后者可能占用大部分CPU时间。

1
可计数循环默认不具备安全点以保持其快速性。例如,参见以下错误:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6869327该错误是为了添加一个标志来关闭此行为(但默认情况下它是开启的)。 - BeeOnRope
你能否也尝试回答我的这个问题,这是我在阅读你的答案后产生的。 - Geek

6

我此刻手头没有相关内容,但在开始分析之前,有一个默认隐藏的设置窗格可以让你输入正则表达式来过滤方法。默认情况下,它会过滤掉很多核心JDK的内容。


0
我在我的宠物项目中遇到了同样的问题。我添加了一个“package”名称,问题得到了解决。我不明白为什么。使用的工具包括:VisualVM 1.4.1、jdk1.8.0_181和jdk-10.0.2,操作系统是Windows 10。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接