【问题标题】:Can't see my own application methods in Java VisualVM在 Java VisualVM 中看不到我自己的应用程序方法
【发布时间】:2011-03-15 15:50:18
【问题描述】:

我正在尝试分析我的 java 应用程序,只是为了找出花费最多时间的方法。鉴于这里对 TPTP 的反应不佳,我想我应该试试 Java VisualVM。

这一切似乎都相当简单易用 - 除了我似乎无法从中获得任何一致或有用的东西。

我似乎看不到任何与 MY OWN 代码相关的内容 - 我得到的只是一大堆对 java.* 方法之类的调用。

我尝试将检测仅限于我自己的包,这似乎减少了检测方法的数量,但我似乎仍然没有看到我自己的。

每次运行时,我都会检测到不同数量的方法,从 10 到 1000 不等。 我尝试在我的应用程序启动时进入睡眠状态,以确保在我的应用程序开始执行任何有趣的事情之前启动并运行 VisualVM,以确保它在有趣的东西运行时进行分析。

我必须做些什么来确保我的课程得到仪表化吗? 有时间问题吗? ..like,必须等待类被加载等? 我还尝试过两次运行代码的核心,以确保所有代码都得到执行...

我只是在 Eclipse 中运行一个带有 main 的应用程序。我尝试使用 Eclipse 集成,以便在我启动应用程序时启动 VisualVM - 结果是相同的。 我还尝试将应用程序导出为可运行的应用程序,并从命令行独立运行,而不是通过 Eclipse - 结果相同。

我的应用程序不是一个长时间运行的网络应用程序等 - 只是一个调用我自己的其他类进行一些处理然后退出的主程序。

对于我可能做错的任何建议,我将不胜感激! :)

谢谢!

【问题讨论】:

  • 我不知道这是否会有所不同,但是您是否在没有任何调试信息的情况下编译了您的应用程序?还是您的应用程序使用自定义类加载器?
  • 有一个简单有效的技巧:stackoverflow.com/questions/266373/…

标签: java profiling


【解决方案1】:

我认为这不仅仅是一个学术问题 - 您想看看是否可以让应用程序运行得更快。我想你也不会介意一些“开箱即用”的想法。有许多流行的关于性能的想法实际上非常模糊。

例如,您说您正在寻找“花费最多时间的方法”。如果你的意思是“自我时间”(实际上在方法中的程序计数器)可能很少,除非你有一些强烈的循环。方法通常会通过调用其他方法来花费时间,有时还会进行 I/O。

另一个模糊的想法是测量方法时间或计算调用次数可以告诉你瓶颈在哪里。瓶颈是特定的代码行,而不是方法,因此即使您大致知道要查找的位置,您仍然在扮演侦探的角色。

所以这些是一些模糊的想法。 Here is a bunch more. 让我建议一个人应该如何思考它,以及它如何导致结果。

当你最终修复某些东西时,它会减少一些执行时间,比如(选择一个数字)30%,对吧? (否则你什么都没有修复。)好吧,在这 30% 的时间里,它正在做一些事情,一些它不需要做的事情,因为后来你摆脱了它。因此,您不需要测量。你确实需要找出它在那段时间在做什么,这样你就知道要摆脱什么了。

一个非常简单的方法是随机“暂停”它 10 次(或若干次)。通过查看调用堆栈和可能的一些数据,了解它在做什么以及为什么。其中大约有 3 次你会看到它在做一些你可以摆脱的事情。

您将大约通过查看显示样本的百分比来了解它会节省多少。 近似值就足够了。您可以通过在前后停止观察来轻松准确地了解节省了多少时间。

那么,不要停下来。您使应用程序变得更快。再做一次,让它更快。迟早你会达到一个无法让它更快的地步,但它可能不止一步。

【讨论】:

    【解决方案2】:

    你可以看看 Appdynamics lite,它有一个很好的特性,比如业务事务发现,它可以对代码中特定方法的所有调用进行采样。

    精简版有很多限制,例如最多 10 分钟的采样和最多 30 个业务事务发现。

    如果有一个免费的工具可以做同样的事情,那就太好了

    【讨论】:

      【解决方案3】:

      我也在为 VisualVM 苦苦挣扎,这很遗憾,因为它的用户界面非常棒,而它的分析输出看起来很可怕。你可以在这里看到我的问题。

      Java VisualVM giving bizarre results for CPU profiling - Has anyone else run into this?

      我可以告诉您一些关于 VisualVM 的奇怪知识以及它似乎进行分析的方式。

      VisualVM 似乎正在计算在方法中花费的总时间(挂钟时间)。我的应用程序中有一个线程,它启动许多其他线程,然后立即阻塞等待队列中的消息。在其他线程之一发送第一个线程正在等待的消息(当应用程序终止时)之前,VisualVM 不会在分析器中注册此方法。突然,阻塞方法调用支配了分析输出,并被记录为占用了超过 80% 的应用程序时间。

      其他探查器,例如 JProfiler 和 Azul 使用的探查器不会将阻塞的线程计算为探查器占用的时间。这意味着对于性能分析可能不感兴趣(取决于情况)的阻塞方法会模糊您对占用 CPU 时间的代码的看法。

      当我运行我的分析时,我最终得到了

      sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run()

      一直隐藏我的分析,直到该消息返回到等待线程,然后这两个完全不相关的方法以及其他各种未出现在其他分析器上的无趣方法共享最高位置。

      其次,我认为方法过滤机制并没有像我预期的那样工作。这意味着我现在无法过滤掉我正在尝试追查的故事。

      不是一个真正有用的答案。我现在看到的解决方案是为 JProfiler 付费 - VisualVM 对于这项任务似乎并不值得信赖。

      【讨论】:

      • 我遇到了和@francis-stephens 一样的问题还没有找到解决方案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-04
      • 2011-06-12
      相关资源
      最近更新 更多