我的应用程序在具有 16 个处理器和 64 GB 内存的服务器上正确运行。我有多个进程,我尝试将我的进程的最大堆限制为 8 GB。
我的问题是我有某种形式的生产者-消费者模式,我必须限制生产速率,否则我会耗尽内存,因为老年代的垃圾收集发生得太少了。
- 当我监控我的应用程序时,我可以看到运行 4 小时后,我在 ParNEW 中花费了 7 分钟,在 ConcurrentMarkSweep 中花费了 0.775 秒。
- 我的堆占用上升到大约 6GB,然后下降到 1GB,然后慢慢开始上升到 6GB,然后再次下降。周期约为 10 分钟
通过 JVisualVM 我可以看到 90% 的内存占用是由 CMS Old Gen 给定的,如何强制并发标记扫描运行得更频繁一些?
@PeterLawrey 评论非常相关,因为我的应用程序运行在应用程序服务器的顶部,该应用程序服务器专为事件驱动处理和数据分区而设计,例如 Terracotta 或 Coherence。底层实现很可能包括用于事件处理的排队系统。
我的问题是限制堆大小不是解决方案,因为正如我所经历的那样,应用程序没有更频繁地进行垃圾收集,而是耗尽了内存。