2013-05-01 20 views
2

當我測試在tomcat中部署的應用程序時,應用程序被掛起。我並排運行visualvm。在應用程序掛起期間,我在visualvm中看到垃圾回收正在進行。我理論上已經讀過,當垃圾收集開始工作時,由於應用程序線程在那段時間停止,系統停止。我想清楚地知道在java中垃圾收集器和性能命中

其他開發人員如何處理這種情況?

如何在不影響系統性能的情況下以有效的方式處理它?

它可以被認爲是內置的固有屬性還是可以有其他有效的解決方案?

因爲JVM可以配置不同的垃圾收集器算法,但在某些時候它必須運行。如果我的理解錯了,請糾正我。

+0

這是不正確的。當程序在JVM中運行以回收不再存在引用的對象時,垃圾回收器的功能*。如果您的應用程序在運行時掛起,則我懷疑機器上存在資源可用性問題。 – CBass 2013-05-01 15:35:38

+0

取決於,在大多數情況下,如果GC嚴重干擾性能,則代碼更可能成爲問題,而不是GC。所以我首先要看的是GC在做什麼以及爲什麼。這是一個巨大的話題,開始閱讀你的GC如何工作。通常這只是糟糕的終身管理,即保留一些你不再需要的東西。 – 2013-05-01 15:40:26

+0

垃圾收集器正在不同的線程上運行(與機器上的所有應用程序一樣)。如果您擁有單個處理器機器,那麼處理器會切換線程(以及正在運行的其他進程的線程)之間的上下文,這會導致速度下降,但這是CPU速度,可用性和內存的函數。您可以使GC的優先級較低,但這隻會導致垃圾內存堆積,並進一步降低性能。 – CBass 2013-05-01 15:41:38

回答

3

首先回答您的主要問題:不,您不必接受您的應用程序掛起。你實際上可以做些什麼。但是,通過調整代碼並使用直接控制GC策略的JVM切換器,可以通過許多方式微調垃圾收集器。然而,這是一個廣泛的話題,沒有一個最好的答案。這實際上取決於您的應用程序和您的環境。你能做的最好的事情是教育自己,這件事:

1)獲取這裏的概述:http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html

2)閱讀關於具體調整方案:

3.)閱讀同一主題的其他SO問題。

這裏有一些規則,我在自己的代碼中使用:

  • 我做從未嘗試通過調用手動System.gc()「的一個好時機」,以提高GC行爲。如果與GarbageCollectorMXBeanMemoryMXBean之類的內容結合使用,可以取代垃圾收集器。

  • 當我發現性能問題可以重現GC的責任時(通常情況並非如此 - 首先要調整其他東西),我研究了Reference的子類的使用,它們有助於我分配不同的GC運行之間的負載,例如我會檢查是否使用WeakHashMap,而不是另一個Map幫助。

  • 我只會使用JVM調整作爲最後的手段。通常很難記錄爲什麼以及如何使用-XX:MaxNewSize-XnoClassGC等參數,我真的不希望人們進一步下調供應鏈,開始​​嘗試自行調整GC,而不瞭解問題的根本原因。

  • 當我真的沒有其他選擇,我嘗試使用-Xms-Xmx第一 - 減少堆的大小有時可以提高垃圾收集的性能,這很容易解釋了。將起始堆大小設置爲最大堆大小可確保不會因新的內存分配而導致暫停 - 可能會重新排列堆內容。我使用的其他設置的效果很好,分別是-XX:+UseParNewGC-XX:+UseTLAB

4

由於GC耗時過長,您的應用程序被掛起。我建議你進行應用程序性能分析,並試着理解爲什麼你的應用程序需要GC運行這麼久。尋找不必要的分配,未使用的對象,沒有任何控制地超出範圍的集合。

我有時會遇到這個問題。該解決方案總是涉及基於應用性能分析的某種優化(我在不同場合使用了New Relic和AppDynamics)。

+0

+1。我會在查找 – 2013-05-01 17:05:53

+0

的東西列表中添加「不必要的分配」,你是對的。不必要的分配是這些GC掛起問題的主要原因之一 – 2013-05-01 21:21:36

3

有兩種方法可以解決這個:

  • 您可以調整通過選擇「低暫停」收藏家,和/或改變各種調節選項JVM的垃圾收集子系統。不幸的是,低停頓收集有成本。您可以縮短GC運行期間系統暫停的時間長度,但另一方面是更多的CPU週期將耗費整體上的垃圾回收和相關事情。

  • 您可以調整應用程序以減少它創建的(長壽命)垃圾的數量,以及它泄漏的內存量。然而,在這裏你也需要小心......因爲一些經典策略(對象池,弱/軟參考緩存)實際上可能會讓事情變得更糟。在嘗試減少分配之前,至少應該首先進行簡介。

還有其他可能的解釋太:

  • 的 「掛起」 可能是不相關的。他們可能是因爲談話緩慢的外部資源。它們可能是線程瓶頸的不幸副作用。

  • 「掛起」可能是整個系統「顛簸」造成的。當您嘗試使用不會全部適合物理內存的堆時,會發生這種情況。系統隨後必須在物理內存和光盤之間交換虛擬內存頁面。垃圾收集(特別是「完整的」GC)可能會引發這種情況。