【发布时间】:2016-10-05 09:23:14
【问题描述】:
我有这个简单的代码:
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);
}
它创建了许多参与者,然后为每个参与者创建一个调度程序。 Actors 本身负责查询 MQ,然后处理消息。
当 ACTOR_COUNT > 30 时,一切正常。但除此之外,我们有内存泄漏(带有消息“Run”的 akka.dispatch.Envelopes 实例正在填满,无法进行垃圾回收)
这很奇怪,因为当我们有更多的演员时,我们就会有更多的消息(每个人每秒 1 条) - 但意外的是,当有更多的演员/消息时,它会停止填充。
时间间隔(1000 毫秒)并不会真正影响情况,它只会让它变慢或变快。
您能帮我解释一下这种行为吗?
谢谢。
更新
这是一个虚拟演员,可以帮助隔离问题。
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 时重现。现在很明显,当演员睡眠时间 > 调度程序间隔时,信封已填满。如果我将睡眠时间从 3000ms 减少到 500ms,问题就消失了。
但是如果我将参与者的数量增加到 30 个(具有相同的睡眠时间 = 3000 毫秒),垃圾收集器也可以使用消息。为什么?看起来 Akka 中的某些东西在该阈值之后开始以不同的方式工作。
【问题讨论】:
-
老实说,这听起来确实很奇怪。你可以添加你的演员接收方法的代码吗?你会使用成为/不成为吗?
-
@DiegoMartinoia 我已经更新了帖子,请看一下