2010-05-07 35 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堆轉儲去完全失控由於意外的使用模式,例如,它會掩蓋掉的問題的真正原因,而是表現出很多代理對象(如果我記得正確)而不是填充虛擬機。

因此,簡而言之,代碼生成和反射可能會導致統計信息出錯。