我在3年前的Solaris系統上運行一個J2EE應用程序,使用的堆大約爲300 MB。從gc日誌中我看到,每天觸發幾次的完整gc需要大約5秒鐘,每次恢復大約200 MB。完整的gc在如此小的堆上花費這麼長時間的原因是什麼?爲什麼一個小堆上的完整gc需要5秒鐘?
我運行java 1.6.0_37。
我在3年前的Solaris系統上運行一個J2EE應用程序,使用的堆大約爲300 MB。從gc日誌中我看到,每天觸發幾次的完整gc需要大約5秒鐘,每次恢復大約200 MB。完整的gc在如此小的堆上花費這麼長時間的原因是什麼?爲什麼一個小堆上的完整gc需要5秒鐘?
我運行java 1.6.0_37。
緩慢的完整GC(和小事件GC)主要是由於硬件設置不良,其次是軟件配置(即GC人體工程學)以及最後存在於堆中的對象數。
看看硬件,您在Solaris上使用的是哪種CPU型號和供應商?它是一個擁有多個核心的SMP系統嗎?你有多個核心線程嗎? GC是否利用了系統中所有可用的虛擬處理器,即垃圾收集是否分佈在多個處理器上?
使GC執行緩慢的另一種情況是,如果堆的一部分從主內存中被交換出來。在這種情況下,換出的內存頁面必須在垃圾回收期間交換,這可能是一個相當耗時的過程。在這種情況下,機器上沒有安裝足夠的物理內存。
系統上的任何其他應用程序是否競爭相同的物理資源,即CPU和內存?
從GC人體工程學角度來看,您使用的是什麼收集器?我會推薦使用多個收集器線程的並行吞吐量收集器或G1收集器。我也建議使用NUMA配置。
一些通用規則:
有關GC人機工程學的更多信息: http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html
感謝您的回覆。我不認爲我可以責怪服務器。除了我的應用程序外,它沒有使用,每個內核有多個內核和兩個線程,並提供大量可用內存。看看vmstat系統的負載非常低。我怎樣才能看到我創建了多少個對象?我可以看到我在gc日誌中使用了多少堆,但我不知道要看看我創建了多少個對象。 (我儘快回覆您關於收集器的問題) – user1329339
我有Solaris和多核Sparc處理器在垃圾收集方面表現不佳的經驗。雖然你有一個沒有負載的SMP系統,並且利用了所有可用的核/線/線程,但CPU可能是一個糟糕的執行者。 –
我確信這是事實,但你和上面的評論都表示,創建大量對象可以使gc變得緩慢,並且我也無法回答如何衡量它。你有什麼好的建議嗎?再次感謝您的回覆。 – user1329339
這真的取決於存儲在堆棧中的對象的數量。 –
代碼是否正在創建和刪除許多對象?這是否發生在很多/所有程序?> – hexafraction
有趣。所以物體的數量在這裏是重要的因素,而不是大小?如果是,我怎樣才能看到我創建了多少個物體? – user1329339