为啥不是所有方法都显示在 VisualVM 分析器中?

Posted

技术标签:

【中文标题】为啥不是所有方法都显示在 VisualVM 分析器中?【英文标题】:Why aren't all methods displayed in VisualVM profiler?为什么不是所有方法都显示在 VisualVM 分析器中? 【发布时间】:2012-12-24 20:52:02 【问题描述】:

我正在使用VisualVM 来查看我的应用程序在哪里运行缓慢。但它没有显示所有方法,可能没有显示所有延迟应用程序的方法。

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

VisualVM 是否有可能隐藏了本身很快的方法?

更新 1

我通过采样器和猜测发现了缓慢的方法。这是从调试日志中调用的toString() 方法,该方法已关闭,但耗时。

Settings 提供了帮助,现在我知道如何看待它了:这取决于 Start profiling from 选项。

【问题讨论】:

您使用的是采样器还是分析器?采样器,井采样,在定义的时间间隔。分析器更准确,但速度要慢很多。 调试日志应该全部用if (log.isDebugEnabled()) 或类似名称包围,以避免在日志调用中发生字符串连接和其他事情。 另请参阅 blogs.oracle.com/nbprofiler/entry/… 和 blogs.oracle.com/nbprofiler/entry/… 以获取有关分析以及如何设置分析根和检测过滤器的更多信息。 【参考方案1】:

除了 Ryan Stewart 提到的过滤器之外,还有一些其他原因可能导致方法可能不会出现在分析器中:

采样配置文件本质上是随机的:每 N 毫秒对所有线程的当前堆栈进行一次采样。一些实际执行但在运行期间未在任何示例中捕获的方法将不会出现。这通常不会有太大问题,因为它们没有出现在任何示例中,这意味着这些方法很有可能不会占用您运行时的大部分时间。 在 visualvm 中使用基于检测的采样(称为“CPU 分析”)时,您需要定义分析方法的入口点(“开始分析从”选项)。我发现默认包中的方法会失败,并且在附加分析器时也不会在当前正在运行的方法中获取时间(在当前调用期间 - 它将获得以后的调用。这可能是因为在当前调用完成之前,检测方法不会被换入。 采样会受到基于堆栈跟踪的分析的潜在严重问题的影响,即仅在代码中的安全点进行采样。当请求跟踪时,每个线程都被强制到一个安全点,然后获取堆栈。在某些情况下,您的代码中可能存在不进行安全点轮询的热点(常见于简单循环,JIT 可以保证在固定次数的迭代后终止),并与一些确实具有安全点轮询的代码交错。您的堆栈将始终在安全点代码中显示您的进程,而不是在安全点空闲代码中,即使后者可能占用大部分 CPU 时间。

【讨论】:

可数循环默认情况下没有安全点来保持快速。例如,请参阅此错误:bugs.sun.com/bugdatabase/view_bug.do?bug_id=6869327 添加一个标志以关闭此行为(但默认情况下它是打开的)。 您是否也可以尝试回答this question of mine,这是阅读您的答案的结果。【参考方案2】:

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

【讨论】:

【参考方案3】:

我的宠物项目也有同样的问题。我添加了一个package 名称,问题就解决了。我不明白为什么。 VisualVM 1.4.1jdk1.8.0_181jdk-10.0.2Windows 10

【讨论】:

以上是关于为啥不是所有方法都显示在 VisualVM 分析器中?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 VisualVM 中 CPU 时间大于挂钟时间?

如何在 VisualVM 中显示调用树?

为啥 visualvm 中的“总时间”列与运行时持续时间不同?

使用 VisualVM 进行 JAVA 远程分析

如何使用 JDK 分析工具?我是不是需要查看分析工具(JConsole 或 VisualVM),直到它出现一些问题?

如何告诉 visualvm 在哪里可以找到我的源代码?