我们最近使用以下配置测试了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垃圾收集器确实倾向于消耗更多内存,但磁盘交换是一个令人担忧的问题。有人可以就如何解决这个问题提供一些指示吗?
答案 0 :(得分:2)
至于评论的长期,我把它作为答案。
一个很好的解读,解释why a java process might consume more memory than -Xmx。根据我们提供的信息,我相信这也是您的理由。
对于G1,有一个OBE Getting Started with the G1 Garbage Collector,其中包含有关G1GC功能的详细信息。看看Recommended Use Cases for G1
。也许你不会从使用G1中受益。
引自OBE( O racle B y E xample)
如果您正在使用CMS或ParallelOldGC并且您的应用程序没有经历长时间的垃圾收集暂停,那么与您当前的收集器保持联系是可以的。
答案 1 :(得分:1)
Here you can find testing results在缩放和资源消耗方面,以及可以应用哪些设置来改善结果的一些建议。因此,您可以为项目选择最合适的一个并减少内存使用量。