此圖表顯示了我們的 Java 應用程序在 4 天內的堆利用率 (OU+EU+S1U+S2U)。每一個 drop 都是一個 Young GC 事件。如您所見,堆使用量呈增長趨勢。Full GC 在運行 6 天后發生(圖中未顯示)。它將堆使用率降低到正常水平,但暫停時間為 2 分鐘,并導致應用程序丟棄許多事務。我們的 JRE 是 8,我們使用并行 GC。堆參數如下: java -server -Xms64g -Xmx64g -XX:MetaspaceSize=96M -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -XX:MaxMetaspaceSize=1g -XX:+UseParallelGC -XX:ParallelGCThreads=4 -XX:+HeapDumpOnOutOfMemoryError -Djava.net.preferIPv4Stack=true -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Dsun.zip.disableMemoryMapping=true我試圖了解什么調整可以使 Young GC 更有效,以便它刪除所有垃圾并避免升級到老年代。
2 回答

ibeautiful
TA貢獻1993條經驗 獲得超6個贊
問題似乎是對象被提升到永久空間然后死亡。減少這種情況的一種方法是使年輕空間更大,但這只會延遲完整收集。
另一種方法可能是減少堆,使其收集更頻繁,從而減少暫停時間。如果您使用 32GB 堆,它可以使用壓縮 oops,從而提高內存使用效率。

九州編程
TA貢獻1785條經驗 獲得超4個贊
正如 Lawrey 先生指出的那樣,您可以使年輕代變大,這將增加(希望如此)次要 GC 事件之間的時間。通過這樣做,更多的對象應該成為垃圾,并將在次要 GC 中收集,而不是提升到舊的 gen。另一種方法是增加任期閾值,這與將對象在年輕代中保持更長時間的效果相同。
另一個要問自己的問題是,你真的需要使用并行 GC 嗎?如果使用 G1,一些收集舊空間的工作是與應用程序線程并發處理的。您可能能夠完全消除長時間的停頓(假設您沒有遭受過多的堆碎片),因為您不需要完整的壓縮集合。
為了完全消除停頓,我可以衷心推薦 Azul 的 Zing 中的 C4 收集器(我為他工作 :-))。
添加回答
舉報
0/150
提交
取消