我正试图解决一个问题,即在我的java服务中,堆内存超过了90%。
下面是我使用的堆配置。
-Xms6144m \
-Xmx6144m \
-verbose:gc \
-XX:G1HeapRegionSize=2097152 \
-XX:+PrintGC \
-XX:+PrintFlagsFinal \
-XX:InitiatingHeapOccupancyPercent=40 \
-XX:NewRatio=2 \
-XX:+PrintGCDetails \
-XX:+PrintGCDateStamps \
-XX:+PrintAdaptiveSizePolicy \
-XX:+PrintTenuringDistribution \
-XX:+UseGCLogFileRotation \
-XX:NumberOfGCLogFiles=10 \
-XX:GCLogFileSize=50M \
-XX:+UnlockExperimentalVMOptions \
-XX:+UseG1GC -XX:+UseStringDeduplication \
-XX:+UseCGroupMemoryLimitForHeap \
-XX:+ParallelRefProcEnabled
-XX:+OptimizeStringConcat
-XX:MaxRAMFraction=2 \
-XshowSettings:vm
问题是我的旧基因逐渐被填满,随着时间的推移,GC后堆的下限也在增加,我的图看起来像这样。
你能建议我的堆参数是否正确,它们在配置方式上是否有冲突,或者我怎样才能减少最大堆被使用?
G1GC主要是为了一件事而设计的,通过保持你的应用响应。
尽量避免 "旧基因 "的垃圾收集(应用程序已经保留了一段时间的持久对象,比如来自用户会话、缓存或某种内存泄漏)必须在一个经典的FullGC中完成,在那里你的应用程序被冻结,而整个堆必须被清理(这取决于对象的数量可能需要很长的时间,比如几秒钟。阅读全部内容 此处,其中有一段话。
目标是尽可能多地回收堆空间(从那些包含最多可回收空间的区域开始) 同时尽量不超过暂停时间目标。
你为...设置的40%与(整个)堆的占用率有关,并表示什么时候开始并发的GC循环(这在日志中应该可以看到,如果没有看到:: InitiatingHeapOccupancyPercent
与(整个)堆的占用率有关,并表示何时开始一个并发的GC循环(这在日志中应该是可见的,如果没有看到。这个相关问题 ). 根据整个堆的占用率而不仅仅是其中一代(所以不仅仅是老一代),包括G1,触发一个并发GC循环的GC使用这个选项。值为0表示 "做恒定的GC循环"。默认值是45。(改编自:Oracle® Communications WebRTC Session Controller。(改编自:Oracle® Communications WebRTC Session Controller系统管理员指南) )
所以有可能是这样的。
Evacuation Failure
如果你真的想让你的应用程序使用更少的内存(也许要以损失一些性能吞吐量为代价),你可以降低MaxHeapSize(但你应该使用其中之一。MaxRAMFraction 或 MaxHeapSize (XmX),而不是两者之一)。)
或者根据你的应用和性能要求,可以考虑选择一个完全不同的JVMGarbage Collector,比如。