gpt4 book ai didi

java - Akka:意外的邮箱填满

转载 作者:行者123 更新时间:2023-11-29 08:41:28 31 4
gpt4 key购买 nike

我有这个简单的代码:

List<ActorRef> actors = new ArrayList<>();
for (int i = 0; i < ACTOR_COUNT; i++) {
actors.add(system.actorOf(...));
}
for (ActorRef actor : actors) {
system.scheduler().schedule(FiniteDuration.create(0, TimeUnit.MILLISECONDS),
FiniteDuration.create(1000, TimeUnit.MILLISECONDS), actor, "Run", system.dispatcher(), null);
}

它创建了许多参与者,然后为每个参与者创建了一个调度程序。 Actor 本身负责查询 MQ,然后处理一条消息。

当 ACTOR_COUNT > 30 时,一切都很好。但除此之外,我们有内存泄漏(带有消息“Run”的 akka.dispatch.Envelopes 的实例正在填满并且无法被垃圾收集)

这很奇怪,因为当我们有更多的 Actor 时,我们就会有更多的消息(每个 Actor 每秒 1 条)- 但出乎意料的是,当有更多的 Actor /消息时,它会停止填满。

时间间隔(1000 毫秒)并没有真正影响情况,它只是让它变慢或变快。

你能为我解释一下这种行为吗?

谢谢。

更新

这是一个虚拟 Actor ,可以帮助隔离问题。

public class MessageQueueTestActor extends UntypedActor {

private static final Logger log = LoggerFactory.getLogger(MessageQueueTestActor.class);

@Override
public void onReceive(Object message) throws Exception {
Thread.sleep(3000);
}
}

问题在 ACTOR_COUNT = 5 时重现。现在很明显,当 actor sleep 时间 > 调度程序间隔时,信封就会填满。如果我将 sleep 时间从 3000 毫秒减少到 500 毫秒,问题就消失了。

但是如果我将 actor 的数量增加到 30 个(相同的 hibernate 时间 = 3000 毫秒),垃圾收集器也可以使用消息。为什么?看起来 Akka 中的某些东西在那个阈值之后开始以不同的方式工作。

最佳答案

这是一个“调试我的代码”问题,不确定它是否应该在这里,但无论如何我都会回答。

调度程序不会将消息排入 actor 自己的邮箱,它使用给定的调度程序来执行此操作。由于您阻塞了默认调度程序中的线程并使用它来进行排队,因此来自调度程序的消息在某一时刻不再到达邮箱(我假设您的默认调度程序有 30 个线程)。更准确地说:他们一个接一个地到达它,而 Actor 在他们收到的每个回合中最多处理 5 条消息。

所以,没有什么是 GC-ed,你只是在不同的地方(默认调度程序)排队不同的东西(Runnable)。如果处理时间大于滴答周期,您的程序将永远无法持续运行。

关于java - Akka:意外的邮箱填满,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39870123/

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