我正在运行一个构建系统。我们过去使用CMS收集器,但是我们开始遭受非常长的full GC周期的困扰,吞吐量(不进行GC的时间)约为90%。因此,我现在决定切换到G1,并假设即使我有更长的总GC时间,暂停时间也会更短,从而确保更高的可用性。所以这个想法似乎比我预期的要好,我几乎3天没有看到任何full GC,吞吐量为97%,整体GC性能要好得多。(所有截图和数据都来自GCViewer)
直到现在(第6天)。今天系统变得非常疯狂。旧空间利用率仅略低于100%。我几乎每2-3分钟就会看到Full GC被触发:
旧空间利用率:
堆大小为20G(总共128G RAM)。我当前使用的标志是:
![Normal](https://istack.dev59.com/wQCz8.webp)
![Berzerk!](https://istack.dev59.com/tsJS1.webp)
![Old space](https://istack.dev59.com/0Qfgf.webp)
-XX:+UseG1GC
-XX:MaxPermSize=512m
-XX:MaxGCPauseMillis=800
-XX:GCPauseIntervalMillis=8000
-XX:NewRatio=4
-XX:PermSize=256m
-XX:InitiatingHeapOccupancyPercent=35
-XX:+ParallelRefProcEnabled
日志记录标志。 我似乎缺少的是 -XX:+ParallelGCThreads=20
(我有32个处理器),默认应该是8个。 我还从Oracle那里了解到,建议为20G堆使用-XX:+G1NewSizePercent=4
,默认值应该为5。
我正在使用Java HotSpot(TM) 64-Bit Server VM 1.7.0_76,Oracle Corporation。
你有什么建议吗? 我有明显的错误吗? 该怎么改变? 如果只给Java 20G,我的需求是否过于贪心?这里的假设是如果分配太多堆,则意味着有更多东西要清理,从而导致更长的GC时间(平民逻辑)。
PS:应用程序不是我的。 对我来说,它是一个盒装产品。
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintAdaptiveSizePolicy -Xloggc:<logfile>
参数打印GC日志,并将其粘贴到Pastebin上,这样更有助于理解G1的决策。如果可以的话,建议尝试Java 8,因为自那以后,G1GC已经经历了很多变化。它的许多启发式算法得到了改进,一些瓶颈也被消除了。据我所知,在7中有一些情况下,G1可能会陷入困境。 - the8472