我使用Akka及其Java API UntypedActor实现了一个Actor系统。在其中,一个actor(类型A)使用getContext().actorOf(...);
按需动态启动其他actor(类型B)。那些B演员会做一些A不再关心的计算。但我想知道:是否有必要在他们完成后清理那些B型演员?如果是这样,怎么样?
getContext().stop(getSelf())
?getSelf().tell(Actors.poisonPill());
? [这就是我现在正在使用的]。文档对此并不清楚,或者我忽略了它。我对Scala有一些基本的了解,但是Akka的来源并不是入门级的东西......
答案 0 :(得分:23)
您所描述的是根据“请求”(在A的上下文中定义)创建的单用途参与者,它处理一系列事件然后完成,对吧?这是绝对正常的,你把它们关闭是正确的:如果你不这样做,它们会随着时间的推移积累而你会遇到内存泄漏。最好的方法是你提到的第一种可能性(最直接的),但第二种也没关系。
一些背景:演员在他们的父母中注册以便可识别(例如,需要在远程处理,但也在其他地方),并且这种注册使他们不被垃圾收集。 OTOH,每个父母都有权访问它创建的子节点,因此没有自动终止(即通过Akka)是有意义的,而是要求在用户代码中显式关闭。
答案 1 :(得分:0)
除了Roland Kuhn的回答之外,您可以创建一组共享相同调度程序的预定义actor,而不是为每个请求创建一个新的actor,或者您可以使用将请求分发到池的路由器演员。
例如,Balancing Pool Router允许您拥有一组特定类型的固定演员共享同一个邮箱:
akka.actor.deployment {
/parent/router9 {
router = balancing-pool
nr-of-instances = 5
}
}
请阅读dispatchers和routing上的文档以获取更多详细信息。
答案 2 :(得分:0)
我正在从AKKA文档中分析(visualvm)样本集群应用程序之一,我看到垃圾收集在每个GC期间清理每个请求actor。无法完全理解使用后明确杀死actor的建议。我的actor系统和actor由SPRING IOC容器管理,我使用spring extension in-direct actor-producer来创建actor。 “聚合器”actor正在每个GC上收集垃圾,我确实监视了可视VM中的实例数。
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class StatsService extends AbstractActor {
private final LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);
@Autowired
private ActorSystem actorSystem;
private ActorRef workerRouter;
@Override
public void preStart() throws Exception {
System.out.println("Creating Router" + this.getClass().getCanonicalName());
workerRouter = getContext().actorOf(SPRING_PRO.get(actorSystem)
.props("statsWorker").withRouter(new FromConfig()), "workerRouter");
super.preStart();
}
@Override
public Receive createReceive() {
return receiveBuilder()
.match(StatsJob.class, job -> !job.getText().isEmpty(), job -> {
final String[] words = job.getText().split(" ");
final ActorRef replyTo = sender();
final ActorRef aggregator = getContext().actorOf(SPRING_PRO.get(actorSystem)
.props("statsAggregator", words.length, replyTo));
for (final String word : words) {
workerRouter.tell(new ConsistentHashableEnvelope(word, word),
aggregator);
}
})
.build();
}
}
答案 3 :(得分:-3)
默认情况下,Actors不会占用太多内存。如果应用程序打算稍后使用actor b,则可以使它们保持活动状态。如果没有,你可以通过毒药关闭它们。只要你的演员没有资源,留下一个演员应该没问题。