由于频繁的垃圾收集导致服务吞吐量低
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了由于频繁的垃圾收集导致服务吞吐量低相关的知识,希望对你有一定的参考价值。
我在具有16GB RAM的系统上运行服务,具有以下配置:
-Xms6144M"
-Xmx6144M
-XX:+UseG1GC
-XX:NewSize=1500M
-XX:NewSize=1800M
-XX:MaxNewSize=2100M
-XX:NewRatio=2
-XX:SurvivorRatio=12
-XX:MaxGCPauseMillis=100
-XX:MaxGCPauseMillis=1000
-XX:GCTimeRatio=9
-XX:-UseAdaptiveSizePolicy
-XX:+PrintAdaptiveSizePolicy
它有大约20个轮询器,每个轮询器都有大小为30的ThreadPoolExecutor来处理消息。最初大约5-6个小时,它每秒能够处理大约130条消息。此后,它每秒只能处理大约40条消息。
我分析了GC日志,发现Full GC变得非常频繁,超过1000MB的数据从Young发展到Old Generation:
看看堆转储我看到很多等待状态的线程类似于:WAITING at sun.misc.Unsafe.park(Native Method)以下类对象获取大多数保留大小:
我认为在服务及其相关库中可能存在小的内存泄漏,这些库随着时间的推移而累积,因此增加堆大小只会推迟这一点。或者可能是因为Full GC变得非常频繁,所有其他线程都经常停止(“停止世界”暂停)。需要帮助来找出此行为的根本原因。
GC模式看起来像内存泄漏。
查看堆转储统计信息,我可以看到等待在线程池中执行的3M任务。
我可以推测,您正在使用具有无限任务队列的线程池。您的入站邮件速率大于系统的处理能力,因此积压正在成长,消耗更多内存,最终导致GC死亡。
根据您的情况,您可以限制线程池的队列大小,也可以尝试优化队列任务的内存占用。
限制队列大小会在先前的处理阶段产生背压。如果它是简单的计时器驱动的轮询器,它是线程池的生产者,则效果将是reducer轮询间隔(因为轮询器将阻止等待队列中的空间)。
任务内存占用的优化只会使您的处理能力平均大于入站任务率,并且问题是由于临时激增造成的。
以上是关于由于频繁的垃圾收集导致服务吞吐量低的主要内容,如果未能解决你的问题,请参考以下文章