让JProfiler忽略CPU视图中的`Thread.sleep()`

时间:2018-03-28 22:48:23

标签: profiling cpu thread-sleep jprofiler

在JProfiler中,在CPU分析器的Call Tree和Hot Spots视图中,我发现JProfiler正在显示一些方法作为不是真正热点的热点。这些方法正在扭曲我的分析工作,因为它们主导着这些CPU视图并使所有其他CPU消费者看起来微不足道。

例如,一个线程执行Thread.sleep(300_000L)(休眠5分钟),然后在while(true)循环中执行一些相对较小的工作。 JProfiler配置为每5秒更新一次视图,并且我已将线程状态选择器设置为“Runnable”。当JProfiler更新视图时,每隔5秒,我会期望该方法的总自激时间保持相对较小,因为线程处于休眠状态而不是处于可运行状态,但相反,我看到自我时间增量约为5秒指示(错误地)整个5秒间隔,线程处于可运行状态。我担心的是,如果我无法过滤掉休眠(等待)状态,该工具将无法用于我的CPU分析。

通过一些测试,我发现当Thread.sleep()调用最终终止时,自我时间再次下降到接近零,并在下次调用Thread.sleep()时再次开始攀升。所以对我来说,似乎JProfiler正在计算当前调用Thread.sleep()的方法统计数据Runnable - 直到方法实际终止,然后这些统计数据被取消。

这是JProfiler中的错误吗?有没有办法让JProfiler不将Thread.sleep()计入Runnable状态,即使长期运行Thread.sleep()的调用也是如此?

我使用的是JProfiler 8.1.4的许可版本。我也尝试过JProfiler 10.1的评估版。

更新

这是一个简单的测试用例,它为我展示了这个问题。我发现,如果我将Thread.sleep()调用移动到单独的方法,则问题就会消失(请参阅内联注释)。这不是一个很好的解决方法,因为我正在分析一个大型应用程序,并且不想更新它调用Thread.sleep()的所有位置。

public class TestProfileSleep {

  public static void main(String... args) {
    new Thread(new Runnable() {
      private void sleep(long millis) throws InterruptedException {
        Thread.sleep(millis);
      }
      public void run() {
        try {
          while (true) {
            Thread.sleep(60_000L);  // profiling this is broken
            //sleep(60_000L); // profiling this works
          }
        }
        catch (InterruptedException ie) {
        }
      }
    }).start();
  }

}

0 个答案:

没有答案