簡體   English   中英

增加次要GC暫停時間

[英]Increase in Minor GC Pause time

我們正面臨與次要GC相關的奇怪問題。 自上個18個月以來一直在生產中的我們的一個應用程序最近開始具有更高的次要gc暫停時間。 從歷史上看,我們的次要GC暫停時間約為30-50毫秒,但是現在,它們大約為110毫秒至400毫秒。 堆配置沒有任何更改,但是已經進行了大量代碼更改。

該應用程序是一個Rest Web服務,運行在托管於包含8個cpu虛擬機和24 GB RAM的雲的tomcat上,並與cassandra進行通信。 我們嘗試通過運行性能測試來重新創建問題,以便在較低的環境中調試該問題,但無法這樣做。 有一個單一的REST服務,在98%的時間中以相似的工作負載調用,但是2%的工作負載有所不同。 由於數據問題,我們無法對這2%的呼叫進行負載測試。

運行負載時,我們發現回收或提升的堆容量與正常情況下差不多(運行負載測試時負載是生產量的8-10倍),但是較小的gc暫停始終小於50毫秒。 (我們確實在生產VM上運行與讀取操作相同的負載)

具有性能測試要求(高負載):

2015-09-15T10:16:51.617+0000: 300001.062: [GC (Allocation Failure) [PSYoungGen: 1922537K->174564K(1922560K)] 2146305K->432640K(4019712K), 0.0604696 secs] [Times: user=0.44 sys=0.00, real=0.06 secs]
2015-09-15T10:16:54.033+0000: 300003.478: [GC (Allocation Failure) [PSYoungGen: 1922383K->174567K(1922560K)] 2180459K->469257K(4019712K), 0.0493751 secs] [Times: user=0.28 sys=0.00, real=0.05 secs]
2015-09-15T10:16:56.468+0000: 300005.912: [GC (Allocation Failure) [PSYoungGen: 1922535K->174570K(1922560K)] 2217225K->504099K(4019712K), 0.0437478 secs] [Times: user=0.27 sys=0.00, real=0.05 secs]
2015-09-15T10:16:58.696+0000: 300008.140: [GC (Allocation Failure) [PSYoungGen: 1922538K->174576K(1922560K)] 2252067K->541818K(4019712K), 0.0407501 secs] [Times: user=0.25 sys=0.00, real=0.04 secs]
2015-09-15T10:17:00.887+0000: 300010.331: [GC (Allocation Failure) [PSYoungGen: 1922544K->174573K(1922560K)] 2289786K->577682K(4019712K), 0.0468752 secs] [Times: user=0.32 sys=0.00, real=0.05 secs]
2015-09-15T10:17:03.142+0000: 300012.586: [GC (Allocation Failure) [PSYoungGen: 1922541K->174581K(1922560K)] 2325650K->617970K(4019712K), 0.0424797 secs] [Times: user=0.26 sys=0.00, real=0.04 secs]
2015-09-15T10:17:05.394+0000: 300014.838: [GC (Allocation Failure) [PSYoungGen: 1922549K->174587K(1922560K)] 2365938K->659487K(4019712K), 0.0425134 secs] [Times: user=0.27 sys=0.00, real=0.04 secs]
2015-09-15T10:17:07.661+0000: 300017.106: [GC (Allocation Failure) [PSYoungGen: 1922555K->174566K(1922560K)] 2407455K->694256K(4019712K), 0.0389039 secs] [Times: user=0.24 sys=0.00, real=0.04 secs]
2015-09-15T10:17:09.951+0000: 300019.395: [GC (Allocation Failure) [PSYoungGen: 1922534K->174577K(1922560K)] 2442224K->726822K(4019712K), 0.0385114 secs] [Times: user=0.29 sys=0.00, real=0.03 secs]
2015-09-15T10:17:12.302+0000: 300021.746: [GC (Allocation Failure) [PSYoungGen: 1922545K->174591K(1922560K)] 2474790K->762111K(4019712K), 0.0400951 secs] [Times: user=0.28 sys=0.00, real=0.04 secs]

但是,對於同一台機器上的同一JVM而言,生產負載要小得多,因此GC的停頓會非常高:

015-09-15T05:36:27.428+0000: 283176.872: [GC (Allocation Failure) [PSYoungGen: 1844205K->125665K(1922560K)] 1991878K->273338K(4019712K), 0.1087286 secs] [Times: user=0.61 sys=0.00, real=0.11 secs]
2015-09-15T05:39:05.945+0000: 283335.390: [GC (Allocation Failure) [PSYoungGen: 1873633K->157526K(1922560K)] 2021306K->305200K(4019712K), 0.1099762 secs] [Times: user=0.58 sys=0.00, real=0.11 secs]
2015-09-15T05:41:43.686+0000: 283493.131: [GC (Allocation Failure) [PSYoungGen: 1905494K->174576K(1922560K)] 2053168K->337666K(4019712K), 0.1249486 secs] [Times: user=0.70 sys=0.00, real=0.13 secs]
2015-09-15T05:45:06.059+0000: 283695.503: [GC (Allocation Failure) [PSYoungGen: 1922544K->174560K(1922560K)] 2085634K->371522K(4019712K), 0.1434632 secs] [Times: user=0.95 sys=0.00, real=0.15 secs]
2015-09-15T05:48:08.511+0000: 283877.955: [GC (Allocation Failure) [PSYoungGen: 1922528K->174576K(1922560K)] 2119490K->404319K(4019712K), 0.1145014 secs] [Times: user=0.76 sys=0.00, real=0.11 secs]
2015-09-15T05:50:49.150+0000: 284038.594: [GC (Allocation Failure) [PSYoungGen: 1922544K->174571K(1922560K)] 2152287K->436331K(4019712K), 0.1178926 secs] [Times: user=0.68 sys=0.00, real=0.12 secs]
2015-09-15T05:54:18.962+0000: 284248.407: [GC (Allocation Failure) [PSYoungGen: 1922539K->174560K(1922560K)] 2184299K->467992K(4019712K), 0.0975615 secs] [Times: user=0.63 sys=0.00, real=0.10 secs]
2015-09-15T05:57:45.177+0000: 284454.621: [GC (Allocation Failure) [PSYoungGen: 1922240K->174577K(1922560K)] 2215672K->501369K(4019712K), 0.1108669 secs] [Times: user=0.75 sys=0.00, real=0.11 secs]
2015-09-15T06:00:55.609+0000: 284645.053: [GC (Allocation Failure) [PSYoungGen: 1922545K->174584K(1922560K)] 2249337K->534084K(4019712K), 0.0970370 secs] [Times: user=0.65 sys=0.00, real=0.10 secs]
2015-09-15T06:03:32.692+0000: 284802.137: [GC (Allocation Failure) [PSYoungGen: 1922552K->174582K(1922560K)] 2282052K->569585K(4019712K), 0.1109909 secs] [Times: user=0.80 sys=0.00, real=0.11 secs]
2015-09-15T06:06:14.975+0000: 284964.420: [GC (Allocation Failure) [PSYoungGen: 1922550K->174586K(1922560K)] 2317553K->599629K(4019712K), 0.0967938 secs] [Times: user=0.41 sys=0.00, real=0.10 secs]

現在,如果較小的GC暫停時間包括卡片掃描,堆棧掃描,舊版掃描和復印時間,在上述情況下,如果兩者都不相同,那么它們應該是相似的,那么GC暫停時間又有何不同呢? 還是我在這里錯過了一些非常基本的東西?

JVM Version Info:
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)

堆參數為:

-XX:+DisableExplicitGC
-XX:GCLogFileSize=10485760
-XX:+HeapDumpOnOutOfMemoryError
-XX:InitialHeapSize=4G
-XX:MaxHeapSize=4G
-Xmn2G
-XX:NumberOfGCLogFiles=25
-XX:+PrintGC -XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution
-XX:SurvivorRatio=10 -XX:-UseAdaptiveSizePolicy
-XX:+UseCompressedOops -XX:+UseGCLogFileRotation
-XX:+UseParallelGC -XX:+UseParallelOldGC

您正在使用並行收集器,它以吞吐量為主要目標 因此,在不同的工作負載下可能做出不同的折衷以達到其吞吐量目標也就不足為奇了。

如果希望它盡量保持低暫停,則必須指定一個暫停時間目標。

官方文檔中明確說明了這一點:

默認情況下,沒有最大暫停時間目標。

因此,令您驚訝的是,您嘗試了所有這些GC參數,卻沒有嘗試前幾段中提供的參數。

如果您是從其他地方進行參數訓練 ,我強烈建議您在沒有先閱讀文檔以了解其用途之前不要這樣做。


編輯:更仔細地查看正在使用的選項,您將固定余料比率並禁用自適應大小策略,這將阻止GC調整新發電量以滿足暫停時間目標。

並且在不同的工作負載(測試與生產)下,對象的年齡分布將有所不同,因此需要標記來自托兒所和外太空的活動對象並對其進行復制。

這一起導致不同的暫停時間。

相反,您可能應該只指定高級目標,並讓啟發式方法適應不斷變化的工作負載。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM