2012-12-12 74 views
3

我們使用以下啓動參數運行JBoss,但遇到長GC時間(> 5分鐘)的問題。極長的GC時間

-Xms116042m -Xmx116042m -XX:PermSize=256M -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -XX:MaxHeapFreeRatio=95 

有關如何最小化GC時間的任何建議?

注:這是16個四核CPU,128GB的Linux機器。

GC日誌:

我看到很多"CMSbailing out to foreground collection"消息在GC日誌:

130904.206: [GC 130904.206: [ParNew: 240819K->25522K(249216K), 0.2391170 secs] 80798776K->80588205K(118799360K), 0.2395380 secs] [Times: user=2.56 sys=0.01, real=0.24 secs] 
130904.799: [GC 130904.799: [ParNew: 247018K->27648K(249216K), 0.2071170 secs] 80809700K->80601600K(118799360K), 0.2075260 secs] [Times: user=2.61 sys=0.00, real=0.21 secs] 
130905.455: [GC 130905.455: [ParNew: 249216K->27648K(249216K), 0.2808950 secs] 80823168K->80644147K(118799360K), 0.2813140 secs] [Times: user=2.66 sys=0.00, real=0.28 secs] 
130905.765: [Full GC (System) 130905.765: [**CMSbailing out to foreground collection** 
131167.602: [CMS-concurrent-mark: 284.753/303.276 secs] [Times: user=909.49 sys=193.05, real=303.23 secs] 
(concurrent mode interrupted): 80616499K->74658646K(118550144K), 554.7507700 secs] 80651365K->74658646K(118799360K), [CMS Perm : 112620K->112582K(262144K)], 554.7511550 secs] [Times: user=784.15 sys=175.10, real=554.65 secs] 
131461.127: [GC 131461.128: [ParNew: 221568K->27648K(249216K), 0.2620780 secs] 74880214K->74691531K(118799360K), 0.2624960 secs] [Times: user=2.28 sys=0.00, real=0.27 secs] 
131461.698: [GC 131461.699: [ParNew: 249216K->27647K(249216K), 0.3827130 secs] 74913099K->74807895K(118799360K), 0.3829550 secs] [Times: user=3.52 sys=0.41, real=0.39 secs] 
131462.754: [GC 131462.754: [ParNew: 249215K->27648K(249216K), 0.3022410 secs] 75029463K->74827673K(118799360K), 0.3026050 secs] [Times: user=2.36 sys=0.02, real=0.30 secs] 
131463.789: [GC 131463.790: [ParNew: 249216K->22291K(249216K), 0.2396390 secs] 75049241K->74841234K(118799360K), 0.2400980 secs] [Times: user=2.38 sys=0.06, real=0.24 secs] 
+3

仍然相關且很好的閱讀 - http://java.dzone.com/articles/how-tame-java-gc-pauses。 – Perception

+0

你如何衡量它? –

+0

***你給這個東西多少內存***? – Makoto

回答

0

一個原因我已經觀察到完整的GC發生是因爲比要求的年輕一代是越早填補這要求將對象複製到老一代。因此,我們可以嘗試以下方法

  1. 設置一個初始大小爲你的年輕一代如下 -XX:新尺寸=500米-XX:MaxNewSize =500米

  2. 您可以設置一個比對年輕一代作爲老一代 -XX的因素:NewRatio = 3

希望這有助於...

1

無論您使用濃標記還是並行gc,清理116 Gb的垃圾東西都將花費大量時間。我總是發現this document是調諧GC最有用的信息來源。 GC調優將專門針對您的應用需求,並沒有通用的解決方案,但有很多可用選項。

G1GC可能會帶來更多的運氣,因爲它會將堆分成許多小部分並獨立掃除它們,但它仍然可能受到隨機OOME的影響。

如果調整GC將無法產生足夠的響應時間,請將該計算機分成多個16至32 Gb RAM的虛擬機並對其進行集羣化。如果它是一個EJB應用程序,並且你正確地烘焙了你的bean,它可能並不像看起來那麼痛苦。

+0

但確實需要很長時間,但是,如果運行CMS而沒有發生併發模式故障,則不應導致長時間_pauses_。虛擬化_在這裏可能是一個解決方案,但是如果不瞭解更多關於用例的知識,我不會去推薦它,這是最好的解決方案。 –

+0

@KristofferE:是的,「最佳解決方案」是一個誇張的陳述。我編輯了答案。 –

0

您可以將初始堆設置爲較小的值。通過這樣做,啓動時間將減少。由於java不想在啓動時分配一個非常大的堆。這將爲GC節省一些時間,因爲它通常會運行一個相對較小的堆。

0

既然你看到消息「併發模式中斷」,並且在GC時代看起來你的世代都沒有滿員,我認爲有一個明確的System.gc()調用導致你的完整GC。嘗試添加JVM參數-XX:+ ExplicitGCInvokesConcurrent以使System.gc()調用可以調用CMS。另外,如果您自己調用System.gc(),請確定原因並在可能的情況下移除。

0

將java堆大小設置得如此接近物理可用內存並不是一個好主意,除了使用-Xmx配置之外,總是會有一小部分開銷被使用。如果你有很多線程,堆棧將需要相當一點。你看過例如「vmstat 1」看看它是否交換?