【问题标题】:Java - function profilingJava - 函数分析
【发布时间】:2018-12-11 05:33:11
【问题描述】:

我们有一个java程序。我想通过在这些函数的入口和返回上调用适当的分析器函数来跟踪一些函数的入口和返回。

跟踪函数入口很简单,因此不会成为本次讨论的一部分。然而,return 有点混乱,因为我们必须在每个返回点添加分析器代码,因此寻找建议我们如何在不弄乱代码的情况下做到最好。

在 C++ 中,这很容易,只需在函数入口处创建一个小型跟踪类的本地实例,该跟踪类的构造函数和析构函数将负责调用分析器函数。但是,java 没有析构函数(finalize 不起作用),因此这种方法是毫无疑问的。

有什么建议/提示吗?

【问题讨论】:

  • 使用分析器...但要注意它会干扰结果。不要相信它在小方法上的计时结果。当您只需要分析几个方法时,您可以使用 try-finally。否则,请考虑 AOP(面向方面​​编程)工具。无论如何,我建议查看stackoverflow.com/questions/504103/… - 它只是远程相关,但表明事情比使用 AOT(提前)编译器更复杂。

标签: java performance profiling


【解决方案1】:

在整个方法体上使用 try/finally 块:

// handle entry
try {
    // function body
} finally {
    // handle return
}

【讨论】:

    【解决方案2】:

    如果您使用的是 JDK 11,并且想要以非常低的开销测量方法执行的时间,您可以创建一个 Flight Recorder 事件。

    @StackTrace(false)
    static class StopWatch extends jdk.jfr.Event {
    }
    
    StopWatch s = new StopWatch();
    try {
      s.begin();
      ...
    } finally {
      s.commit();
    }
    

    要记录,请使用以下命令启动 JVM:

    java -XX:StartFlightRecording:filename=dump.jfr
    

    当 JVM 存在时会写入录音。然后可以在 JDK Mission Control 中打开它。也就是说,向热门方法添加检测可能会导致结果出现偏差,而采样通常是更好的方法,在这种情况下,您可以直接使用 Flight Recorder,而无需添加代码。

    【讨论】:

    • 你好@Kire Haglin 非常感谢,这是一个救生员。请问这个方法能不能在火焰图中输出可以使用/查看的整个堆栈,看看哪个子方法消耗的时间最多?如果你能帮我检查这个问题会很棒stackoverflow.com/questions/69211369/…
    • 不,您需要一个采样分析器。您可以使用 JFR 提高采样率,因此您更有可能看到子方法,但这可能不足以帮助您。如果您从命令行运行,您可以在 JMC 录制向导或窗口 -> 模板管理器中设置采样率。请参阅“方法分析”。
    • 在 JDK 17 中,你可以这样做: $ java -XX:StartFlightRecording:method-profiling=max,filename=dump.jfr ...
    猜你喜欢
    • 1970-01-01
    • 2010-11-19
    • 2012-03-06
    • 2018-09-12
    • 2020-02-25
    • 2011-07-19
    • 1970-01-01
    • 2010-09-15
    相关资源
    最近更新 更多