2013-01-09 32 views
11

我們遇到了一些奇怪的JVM性能問題。爲什麼java.lang.Object.getClass()(和reflection)比平常慢?

我們有一個很大且有點不透明的GUI組件(Actuate Formula 1電子表格)。

如果我們從Event Dispatch Thread(如您應該)初始化它的全部內容,我們會發現代碼運行速度要慢得多(拖動鼠標選擇單元格,顯着延遲)。

如果我們在主啓動程序線程中第一次初始化它,然後纔開始在EDT中使用它,它運行得更快。

當我看着它爲什麼執行慢慢使用分析,即正在採取一切時間的方法調用:

  • java.lang.Object.getClass()
  • 的java.lang .reflect.Array.newInstance(類,INT)
  • java.lang.Class.getComponentType()
  • java.lang.Thread.currentThread()

我們使用Windows 7(JDK附帶的那個)上的64位Sun Hotspot JVM。

有沒有人知道爲什麼上述方法可能會執行速度比平時慢很多?

我在想,也許它與類的加載順序有關......是一個合理的理論嗎?有沒有人知道我可以診斷爲什麼這些方法調用可能需要很長時間的其他方式?

我附上了兩個截圖。在這兩者中,我所做的只是在探查器運行時將鼠標拖到電子表格單元格周圍。所以它只是更新GUI組件而不做其他事情。

第一個花費大量時間在名爲「releaseLock()」的方法中。出於某種原因,這需要很長時間,因爲「getComponentType()」比平時花費的時間要長。

releaseLock

第二個是我沒有經過「黑客」刪除的「RELEASELOCK()」成本 - 但現在它只是花費大量的時間在「GETLOCK()」由於的getClass()和currentThread()花費更長的時間比正常情況:

getLock

但重要的是,如果我只是改變其中的代碼初始化的順序,沒有這個代碼需要很長時間來執行(它不甚至不會出現在剖析器中)。

如果我要優化getLock(),應用程序仍然執行得更慢。這個問題似乎確實是像getClass()這樣的方法耗時太長。無法彌補這一點 - getClass()在太多地方被調用!

即使沒有運行探查器,性能差異也很明顯。

請注意,我們不能更改任何此代碼 - 它是一個外部組件。我們面臨的挑戰是解釋爲什麼代碼在某些情況下比其他情況執行得更慢。

+1

你可以發佈剖析的截圖嗎?此外,分析可能會對運行時產生重大影響。你能排除這些方法從分析,並看看是否有其他原因,你的滯後? – jlordo

+0

我不知道如何從剖析中排除這些方法,但您可以看到它正在使用採樣並顯示故障。我認爲profiler顯示的是有效的 - 並不是它執行的是不同的代碼,只是出於某種原因,這些通常非常便宜的方法調用(Object.getClass())現在需要很長時間。 –

+1

這個結果是否一致?因爲如果它只發生一次,那麼它很容易成爲一個抽樣問題(在選擇樣本時選擇「運氣不好」)。 –

回答