Акка: Очистка динамически созданных актеров необходима, когда они закончили? - PullRequest
21 голосов
/ 05 марта 2012

Я реализовал систему Actor, используя Akka и ее Java API UntypedActor. В нем один актер (тип A) запускает других актеров (тип B) динамически по требованию, используя getContext().actorOf(...);. Те актеры B сделают некоторые вычисления, о которых A больше не заботится. Но мне интересно: нужно ли убирать тех актеров типа В, когда они закончат? Если да, то как?

  • Когда Б актеры звонят getContext().stop(getSelf()), когда они закончили?
  • Когда актеры группы B звонят getSelf().tell(Actors.poisonPill());, когда они закончат? [это то, что я сейчас использую].
  • Ничего не делая?
  • По ...?

В документах нет ясности по этому поводу, или я упустил это из виду. У меня есть некоторые базовые знания о Scala, но источники Akka не совсем начальные материалы ...

Ответы [ 4 ]

23 голосов
/ 06 марта 2012

То, что вы описываете, - это актеры специального назначения, созданные по «запросу» (определенному в контексте A), которые обрабатывают последовательность событий и затем выполняются, верно? Это абсолютно нормально, и вы правы, чтобы закрыть их: если вы этого не сделаете, они будут накапливаться со временем, и вы столкнетесь с утечкой памяти. Лучший способ сделать это - первая из упомянутых вами возможностей (самая прямая), но вторая тоже подойдет.

Немного предыстории: актеры регистрируются в своих родителях, чтобы их можно было идентифицировать (например, необходимо для удаленного взаимодействия, но также и в других местах), и эта регистрация не позволяет собирать мусор. OTOH, каждый родитель имеет право доступа к созданным им дочерним элементам, поэтому автоматическое завершение (например, Akka) не имеет смысла, вместо этого требуется явное завершение работы в коде пользователя.

0 голосов
/ 20 января 2018

Я профилировал (visualvm) одно из примеров кластерного приложения из документации AKKA, и я вижу, как сборщик мусора очищает участников каждого запроса во время каждого GC. Невозможно полностью понять рекомендацию явно убить актера после использования. Моя система актеров и актеры управляются контейнером SPRING IOC, и я использую весеннее расширение для непосредственного создания актеров. Актор " aggregator " собирает мусор на каждом ГХ, я контролировал количество экземпляров в визуальной ВМ.

@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();
    }
}
0 голосов
/ 19 мая 2015

В дополнение к ответу Роланда Куна, вместо создания нового субъекта для каждого запроса, вы можете создать предварительно определенный набор участников, которые совместно используют один и тот же диспетчер, или вы можете использовать маршрутизатор, который распределяет запросы по пулу субъектов.

Например, Balancing Pool Router позволяет фиксированному набору актеров определенного типа совместно использовать один и тот же почтовый ящик:

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

Прочтите документацию на диспетчеры и маршрутизация для получения более подробной информации.

0 голосов
/ 06 марта 2012

Актеры по умолчанию не занимают много памяти.Если приложение намеревается использовать актера b позже, вы можете сохранить их.Если нет, вы можете отключить их с помощью яда.Пока ваши актеры не располагают ресурсами, уйти с актера должно быть хорошо.

...