gpt4 book ai didi

java - 并发 Mark Sweep Collection 发生的频率不够

转载 作者:行者123 更新时间:2023-11-30 06:28:31 25 4
gpt4 key购买 nike

我的应用程序在具有 16 个处理器和 64 GB Ram 的服务器上正确运行。我有多个进程,我尝试将进程的最大堆限制为 8 GB。

我的问题是我有某种形式的生产者-消费者模式,我必须限制生产率,否则我会耗尽内存,因为老年代的垃圾回收很少发生。

  • 当我监控我的应用程序时,我可以看到在运行 4 小时后,我在 ParNEW 上花费了 7 分钟,在 ConcurrentMarkSweep 上花费了 0.775 秒。
  • 我的堆占用高达 6GB 左右,然后下降到 1GB,然后慢慢开始上升到 6GB,然后再次下降。周期大约为 10 分钟

通过JVisualVM我可以看到我90%的内存占用是由CMS Old Gen给出的,我怎样才能强制并发标记扫描更频繁地运行一点?


@PeterLawrey 评论非常相关,因为我的应用程序运行在应用程序服务器之上,该应用程序服务器专为事件驱动处理和数据分区而设计,例如 Terracotta 或 Coherence。底层实现很可能包括用于事件处理的排队系统。

我的问题是限制堆大小不是解决方案,因为正如我所经历的那样,应用程序没有更频繁地进行垃圾回收,而是内存不足。

最佳答案

I have to limit the producing rate or I will run out of memory

如果您使用无限队列,就会发生这种情况。如果您的生产者超过消费者的速率,队列可以无限制地增长,直到您用完内存。限制生产者可以确保队列保持在合理的大小。

一个简单的解决方法是在队列太长时延迟生产者。

private final BlockingQueue<Task> tasks = new ArrayBlockingQueue<Task>(1000);

// the producer slows when the queue length gets too long.
tasks.offer(newTask, 1, TimeUnit.HOURS);

这将确保队列永远不会变得太长,但不会不必要地减慢生产者的速度。

顺便说一句:与链接队列相比,使用 ArrayBlockingQueue 还可以减少产生的垃圾量。

如果你真的需要一个无界队列,你可以使用我写的一个库,但它的级别相对较低。 Java Chronicle生产者可以超过消费者前面的主内存大小。它仅受磁盘空间大小的限制。

关于java - 并发 Mark Sweep Collection 发生的频率不够,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12461788/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com