G1 垃圾收集器的高内存使用问题

Ani*_*pta 3 java memory garbage-collection g1gc

我们最近使用以下配置测试了 G1 垃圾收集器:

-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseG1GC -XX:MaxGCPauseMillis=1250 -XX:+PrintTenuringDistribution -Xloggc:${logdir}/gc-$(date +%Y_%m_%d -%H_%M).log -XX:+UseStringDeduplication -XX:+PrintStringDeduplicationStatistics -XX:+PrintPromotionFailure -XX:+PrintAdaptiveSizePolicy -XX:+PrintHeapAtGC -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=15 -XX:ParallelGCThreads=8 -XX:+ParallelRefProcEnabled -XX:G1HeapRegionSize=8M JAVA_OPTS_HEAP: -Xms16g -Xmx16g

我们最近遇到一个问题,两个 java 进程在具有 48 GB RAM 的机器上以上述配置运行,并且两个进程各自消耗大约 20 - 22 GB RAM(少数小进程消耗剩余内存) ,从而填满整个 RAM,然后触发磁盘交换,最终导致 OOM 和进程被杀死。

这似乎令人担忧,因为 NMT 都没有以有意义的方式报告内存使用情况,我们也没有从 GC 日志中获得任何有关此使用情况的线索。在 NMT 统计中,应用程序内存低于 16G,元空间使用量低于 1G。

我们尝试将 maxMetaSpaceSize 设置为 2G,但这也没有帮助。当进程运行数天时,RAM 使用量似乎会无限增长。

从其他问题来看,G1 垃圾收集器确实倾向于消耗更多内存,但磁盘交换是一个令人担忧的问题。有人可以提供一些有关如何解决此问题的指示吗?

Sub*_*mal 5

至于渴望发表评论,我将其作为答案。

一本很好的读物,它解释了为什么 java 进程可能比 -Xmx 消耗更多的内存。根据我们提供的信息,我相信这也是您的情况的原因。

对于 G1,有 OBE G1 垃圾收集器入门,其中详细介绍了 G1GC 的功能。去那里看看Recommended Use Cases for G1。也许您不会从使用 G1 中受益。

引自 OBE(O racle B y E xample)

如果您使用 CMS 或 ParallelOldGC 并且您的应用程序没有经历长时间的垃圾收集暂停,那么保留当前收集器就可以了。