2010-05-07 52 views
1

我正在使用YourKit和JProfiler中的采样性能分析功能来分析程序,并且还“手动”(我启动它并按Ctrl-Break几次以获取线程转储)。奇怪的性能分析结果:绝对不会出现瓶颈方法

这三种方法都给我带来了极其奇怪的结果:在3线方法中花费了几十个百分点的时间,即使不进行任何分配或同步也没有循环等。这个方法变成了一个NOP,甚至完全删除了它的调用,可观察的程序性能根本没有改变(虽然它获得了可忽略的内存泄漏,因为它是一种释放廉价资源的方法)。

我在想,这可能是因为JVM放在线程的堆栈跟踪时刻的约束,而且它在某种程度上证明了在我的程序中它恰好是调用此方法的时刻尽管对它或者它所调用的上下文没有特别的要求。

什么可以解释这种现象? 上述约束是什么? 我可以采取哪些进一步措施来澄清情况?

+0

你能发布具体信息吗? – 2010-05-07 12:52:05

+0

@Jeff哪些? – jkff 2010-05-07 12:59:20

+0

也许探查器结果的快照开始 – 2010-05-07 13:12:43

回答

0

在我看来,这些结果只显示这个方法被调用了很多次。由于它的代码非常小,并且可能被称为调用树叶,因此它对分析结果的影响似乎是不可忽视的。但是,我有很多时间那种奇怪的结果。

+0

这个方法被调用的次数不会超过周围更重的方法;此外,当我将此方法设为无效时,程序性能没有明显改变。 – jkff 2010-05-07 13:37:33

0

当你做了几次Ctrl-Break并得到了线程转储时,我很好奇你看到了什么。在我看来,调用堆栈是最有用的信息。如果你的3班轮班时间很长,那么你可以通过查看呼叫的位置以及呼叫的位置等来了解为什么。这些呼叫站点对时间负责被用作3班轮是。

如果堆栈跟踪看起来没有意义,可能是因为它们被延迟到某些事情完成之后。如果是这样,请查看堆栈以查看刚刚完成的内容,因为中断可能发生在内部。

+0

我在帖子中说我尝试过。 – jkff 2010-05-07 13:36:37

+0

@jkff:对不起,我读得太快了。我重新编辑了回复。 – 2010-05-07 14:04:14

0

一些第三方库引起,如果使用cglib堆转储去完全失控由于意外的使用模式,例如,它会掩盖掉的问题的真正原因,而是表现出很多代理对象(如果我记得正确)而不是填充虚拟机。

因此,简而言之,代码生成和反射可能会导致统计信息出错。