我一直在使用Yourkit 8.0来分析在Mac OS X(10.5.7,Apple JDK 1.6.0_06-b06-57)下运行的数学密集型应用程序,并注意到CPU分析结果中存在一些奇怪的行为。 / p>
例如 - 我使用抽样进行了分析运行,它报告了应用程序的10分钟运行时间的40%用于StrictMath.atan方法。我发现这令人费解,但我接受了它的话,花了一点时间用非常简单的多项式拟合替换atan。
当我再次运行应用程序时,它几乎与以前完全相同(10分钟) - 但我的atan替换在分析结果中无处可见。相反,其他主要热点的运行时百分比只是增加以弥补它。
总结:
结果与StrictMath.atan(本地方法)
总运行时间:10分钟
方法1:20%
方法2:20%
方法3:20%
StrictMath.atan:40%
结果简化,纯Java atan
总运行时间:10分钟
方法1:33%
方法2:33%
方法3:33%
(方法1,2,3不执行任何atan调用)
知道这种行为是什么吗?我使用EJ-Technologies的JProfiler获得了相同的结果。似乎JDK概要分析API报告了本机方法的不准确结果,至少在OS X下。
答案 0 :(得分:3)
这可能是因为取样时不一致。因此,例如,如果方法使用相当长的时间,但执行时间不长,则采样可能会错过它。此外,我认为垃圾收集在样本期间从未发生,但如果某些代码导致大量垃圾收集,则可能会导致速度减慢,而不会出现在样本中。
在类似的情况下,我发现运行两次非常有帮助,一次是跟踪,一次是采样。如果一个方法出现在两者中,它可能使用了大量的CPU,否则它很可能只是采样过程的一个人为因素。
答案 1 :(得分:0)
我发现YourKit极大地夸大了调用子方法的成本(由于它的记录方法,我假设)。如果你只是按照配置文件给你的建议,你最终只会合并功能而没有真正的收益,因为HotSpot通常会为此做得非常好。
因此,我强烈建议在分析器之外完全测试批次,以便更好地了解变化是否真正有益(这看起来很明显,但这花费了我一些开发时间)。
答案 2 :(得分:0)
由于你使用的是Mac,你可能会尝试Apple's Shark profiler(从ADC免费下载),它有Java支持,Apple的性能组已经花了相当多的时间进入该工具。
正如Nick指出的那样,如果采样间隔足够接近函数的执行时间,并且探查器很少检查函数何时实际执行,则采样可能会产生误导。我不知道YourKit是否支持此功能,但在Shark中,您可以将采样间隔更改为默认值10ms以外的其他值,并查看结果是否有很大差异。 还有一个单独的调用跟踪模式,它将记录每个函数的进入/返回 - 这完全避免了混叠错误的可能性,但收集了大量数据和更高的开销,这可能很重要,如果您的应用程序正在进行任何类型的实时处理
答案 3 :(得分:0)
您可能希望查看传递给这三种方法的参数。可能是生成返回值所花费的时间,或者是创建大量临时对象的方法。
答案 4 :(得分:0)
值得注意的是,如果Java方法足够小,可以内联,但本机方法在不同规则下内联。如果方法是内联的,它不会出现在探查器中(当然不是YourKit)
答案 5 :(得分:-1)