我有一个高容量Java应用程序,可以处理50000msgs /秒的一致负载。它使用以下设置进行了高吞吐量调整:
-Xmx3g -Xms3g -XX:NewSize = 2g -Xss128k -XX:SurvivorRatio = 6 -XX:TargetSurvivorRatio = 90 -XX:+ UseParallelGC -XX:ParallelGCThreads = 12 -XX:+ UseParallelOldGC -XX:+ HeapDumpOnOutOfMemoryError
虽然GC的运行频率保持不变,但我发现年轻的GC时间从50毫秒开始稳步上升到当天结束时的200毫秒。
如果我使用ParNewGC收集器尝试相同的运行,GC时间会以更快的速度上升。有没有人对这个问题有任何想法?
答案 0 :(得分:3)
如果您有内存泄漏,或内存缓存逐渐使用越来越多的内存,这些会导致GC执行更多工作来跟踪可访问的对象。
其他可能性是:
您有非堆内存泄漏,这导致增加分页;即将物理内存页面复制到光盘和后面。
某些外部进程正在消耗越来越多的内存,导致分页越来越多。
年轻一代中生成的对象的性质随着时间的推移而变化,因此需要更多的工作来跟踪可到达的对象。可能只是因为其中较大比例的人在第一次收集后幸存下来。
答案 1 :(得分:2)
这可能是几个因素的组合:
为什么不绘制对象数量,堆大小和gc-time。 (使用工具,或通过查询MBean)情节应该告诉你趋势;增加,减少或线性,并将帮助您确定是否有泄漏。如果可能,还要从您的程序中转储一些统计信息,例如已处理的消息数或活动会话等。
这是一个真正的问题,因为你的消息在gc期间没有得到处理吗?尝试并发标记和扫描gc ......
* -XX:+UseConcMarkSweepGC -XX:+UseParNewGC