22

AkkaとそのJavaAPIUntypedActorを使用してActorシステムを実装しました。その中で、1つのアクター(タイプA)は、を使用して、オンデマンドで他のアクター(タイプB)を動的に開始しgetContext().actorOf(...);ます。これらのBアクターは、Aがもう気にしない計算を実行します。しかし、私は疑問に思っています。タイプBのアクターが終了したら、それらをクリーンアップする必要がありますか?もしそうなら、どのように?

  • 終わったらB俳優に電話getContext().stop(getSelf())してもらうことで?
  • 終わったらB俳優に電話getSelf().tell(Actors.poisonPill());してもらうことで?[これは私が今使っているものです]。
  • 何もしないで?
  • に ...?

ドキュメントはこれについて明確ではないか、私はそれを見落としました。私はScalaの基本的な知識を持っていますが、Akkaのソースは厳密にはエントリーレベルのものではありません...

4

4 に答える 4

23

あなたが説明しているのは、「リクエスト」(Aのコンテキストで定義)ごとに作成された単一目的のアクターであり、一連のイベントを処理してから実行されます。それは絶対に問題ありません。シャットダウンするのは正しいことです。シャットダウンしないと、時間の経過とともに蓄積され、メモリリークが発生します。これを行うための最良の方法は、あなたが言及する最初の可能性(最も直接的な)ですが、2番目も大丈夫です。

少し背景があります。アクターは、識別可能にするために親内で登録され(たとえば、リモーティングだけでなく他の場所でも必要)、この登録により、アクターがガベージコレクションされるのを防ぎます。OTOH、各親は作成した子にアクセスする権利を持っているため、自動終了(つまり、Akkaによる)は意味がなく、代わりにユーザーコードを明示的にシャットダウンする必要があります。

于 2012-03-06T14:57:30.650 に答える
0

Roland Kuhnの回答に加えて、リクエストごとに新しいアクターを作成するのではなく、同じディスパッチャーを共有する事前定義されたアクターのセットを作成するか、アクターのプールにリクエストを配信するルーターを使用できます。

たとえば、バランシングプールルーターを使用すると、特定のタイプのアクターの固定セットで同じメールボックスを共有できます

akka.actor.deployment {
  /parent/router9 {
    router = balancing-pool
    nr-of-instances = 5
  }
}

詳細については、ディスパッチャルーティングに関するドキュメントをお読みください。

于 2015-05-19T16:19:12.323 に答える
0

AKKAドキュメントからサンプルクラスターアプリケーションの1つをプロファイリング(visualvm)していましたが、ガベージコレクションがすべてのGC中にリクエストごとのアクターをクリーンアップしているのがわかります。使用後にアクターを明示的に殺すという推奨事項を完全に理解することはできません。私のアクターシステムとアクターはSPRINGIOCコンテナーによって管理されており、SpringExtensionの間接アクタープロデューサーを使用してアクターを作成しています。「アグリゲーター」アクターはすべての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();
    }
}
于 2018-01-20T05:25:28.030 に答える
-3

デフォルトでは、アクターは多くのメモリを消費しません。アプリケーションが後でアクターbを使用する予定の場合は、それらを存続させることができます。そうでない場合は、poisonpillを介してそれらをシャットダウンできます。アクターがリソースを保持していない限り、アクターを残すことは問題ありません。

于 2012-03-06T01:25:46.147 に答える