我有一個運行在(大)圖上的Java程序。因此,它使用了大量的堆空間(大約50GB,大約是主機上物理內存的25%)。在某一點上,程序(重複)從圖中選取一個節點並用它進行一些計算。對於某些節點,這種計算花費的時間比預期長得多(30-60分鐘,而不是預計的幾秒鐘)。爲了剖析這些操作以找出花費那麼多時間,我創建了一個測試程序,僅創建大圖的一小部分,然後在需要很長時間計算的節點之一上運行相同的操作原來的程序。因此,與原始程序相比,測試程序顯然只使用非常小的堆空間。Java的大堆比較慢
事實證明,在測試程序中,在原始程序中花了48分鐘的操作可以在9秒內完成。這真讓我困惑。首先想到的可能是較大的程序花費大量的時間進行垃圾回收。所以我打開了虛擬機垃圾收集器的詳細模式。據此,在48分鐘內沒有完整的垃圾收集,而年輕一代只收集約20個垃圾收集,每個垃圾收集少於1秒。
所以我的問題是還有什麼可以解釋這樣一個巨大的時間差異?我不太瞭解Java如何組織堆。有大量實時對象的大堆需要更長的時間嗎?難道在這種環境下對象分配需要更長的時間,因爲在堆中找到足夠的位置需要更長的時間?或者,虛擬機會對堆進行任何內部重組,這可能需要很長時間(顯然,除了垃圾回收之外)。
我正在使用Oracle JDK 1.7,如果這是任何重要的。
不知道你的程序做了什麼樣的操作,這是不可能回答的。 –
測試和主程序還有什麼不同,比可分配堆的數量還多?他們是否使用其他類型的數據?測試應用程序使用了多少堆,如果僅使用小堆,則使用短指針的性能選項(但這無法解釋您的性能差異) – ooxi
您應該使用良好的分析器(例如YourKit)來分析緩慢的原因,我發現很難相信這裏的任何人都能猜出問題的根源。 – alfasin