Поделиться через


Жизненный цикл субъектов, автоматическая сборка мусора и удаление вручную

Субъект активируется при первом вызове любого из его методов. Субъект деактивируется, если он не используется в течение заданного периода времени (при этом среда выполнения субъектов собирает мусор). Субъект и его состояние можно также удалить вручную в любое время.

Активация субъекта

При активации субъекта происходит следующее:

  • При поступлении вызова для субъекта, который еще не активен, создается новый субъект.
  • Загружается состояние субъекта (если это субъект с отслеживанием состояния).
  • Вызывается метод OnActivateAsync (C#) или onActivateAsync (Java) (он может быть переопределен в реализации субъекта).
  • После этого субъект считается активным.

Деактивации субъекта

При деактивации субъекта происходит следующее:

  • Если субъект не используется в течение некоторого периода времени, он удаляется из таблицы активных субъектов.
  • Вызывается метод OnDeactivateAsync (C#) или onDeactivateAsync (Java) (он может быть переопределен в реализации субъекта). Это приводит к сбросу все таймеров для субъекта. Операции с субъектом, такие как изменение состояния, не должны вызываться из этого метода.

Совет

Среда выполнения субъектов Service Fabric генерирует некоторые события, связанные с активацией и деактивацией субъектов. Они полезны при диагностике и мониторинге производительности.

Сборка мусора и субъекты

При деактивации субъекта освобождаются ссылки на объект этого субъекта, так сто он может быть удален сборщиком мусора среды CLR или виртуальной машины Java. Сборщик мусора удаляет только объект субъекта; он не удаляет состояние, сохраненное в диспетчере состояний субъектов. При следующей активации субъекта создается новый объект субъекта и восстанавливается его состояние.

Что считается "использованием" субъекта в контексте деактивации и сборки мусора?

  • Получение вызова
  • IRemindable.ReceiveReminderAsync (применимо только в том случае, если субъект использует напоминания).

Примечание

Если субъект использует таймеры и выполняется обратный вызов по таймеру, он не считается "используемым".

Прежде чем перейти к подробному рассмотрению деактивации, важно определить два понятия:

  • Интервал сканирования. Это интервал, с которым среда выполнения проверяет таблицу активных субъектов, чтобы определить, какие субъекты можно деактивировать и удалить во время сборки мусора. По умолчанию интервал равен 1 минуте.
  • Время ожидания в состоянии простоя. Это период времени, в течение которого субъект должен находиться в неиспользуемом состоянии (в состоянии простоя) до того, как он будет деактивирован и удален сборщиком мусора. По умолчанию это время равно 60 минутам.

Как правило, эти значения изменять не требуется. При необходимости этот период времени можно изменить, вызвав метод ActorServiceSettings при регистрации службы субъектов:

public class Program
{
    public static void Main(string[] args)
    {
        ActorRuntime.RegisterActorAsync<MyActor>((context, actorType) =>
                new ActorService(context, actorType,
                    settings:
                        new ActorServiceSettings()
                        {
                            ActorGarbageCollectionSettings =
                                new ActorGarbageCollectionSettings(10, 2)
                        }))
            .GetAwaiter()
            .GetResult();
    }
}
public class Program
{
    public static void main(String[] args)
    {
        ActorRuntime.registerActorAsync(
                MyActor.class,
                (context, actorTypeInfo) -> new FabricActorService(context, actorTypeInfo),
                timeout);
    }
}

Для каждого активного субъекта среда выполнения субъектов хранит информацию о времени, в течение которого он простаивает (не используется). Среда выполнения проверяет каждый субъект с интервалом ScanIntervalInSeconds, определяет, можно ли выполнить сбор мусора, и помечает субъект, если он бездействует в течение IdleTimeoutInSeconds.

При каждом использовании субъекта его время ожидания в состоянии простоя обнуляется. После этого субъект может быть удален сборщиком мусора только после бездействия в течение интервала времени, равного IdleTimeoutInSeconds. Считается, что субъект был использован, если метод вызван через интерфейс субъекта или если выполнен обратный вызов по напоминанию. Не считается, что субъект был использован, если выполняется обратный вызов по таймеру.

На следующей схеме показан жизненный цикл одного субъекта, демонстрирующий описанные принципы.

Пример времени простоя

В примере показано влияние вызова методов субъекта, напоминаний и таймеров на время жизни субъекта. Обратите внимание на следующие важные моменты:

  • ScanInterval и IdleTimeout установлены в 5 и 10 соответственно. (Единицы не имеют значения, поскольку наша цель — лишь проиллюстрировать концепцию.)
  • Поиск субъектов, которые нужно удалить во время сборки мусора, происходит при T = 0, 5, 10, 15, 20 и 25, так как интервал сканирования равен 5.
  • Таймер срабатывает при T = 4, 8, 12, 16, 20 и 24, после чего выполняется обратный вызов. Это не влияет на время простоя субъекта.
  • Вызов метода субъекта при T = 7 обнуляет время ожидания в состоянии простоя и откладывает удаление субъекта при сборке мусора.
  • При T = 14 выполняется обратный вызов по напоминанию, что снова откладывает удаление субъекта при сборке мусора.
  • На момент поиска объектов, которые можно удалить при сборке мусора, при T = 25 время простоя субъекта превышает заданное значение IdleTimeout (10) и субъект удаляется сборщиком мусора.

Субъект никогда не удаляется сборщиком мусора, если выполняется какой-либо из его методов, независимо от того, сколько времени занимает выполнение этого метода. Как упоминалось ранее, выполнение методов, определенных в интерфейсе субъекта, и обратных вызовов по напоминанию предотвращает сборку мусора, так как время простоя субъекта обнуляется. Выполнение обратных вызовов по таймеру не обнуляет время простоя. Однако сборка мусора для субъекта откладывается до завершения выполнения функции обратного вызова по таймеру.

Удаление субъектов и данных их состояния вручную

При удалении деактивированных субъектов удаляется только объект субъекта; из диспетчера состояний субъекта данные не удаляются. При повторной активации субъекта его данные снова становятся доступны в диспетчере состояний. Если субъекты, данные которых хранятся в диспетчере состояний, деактивируются и больше не активируются, может возникнуть необходимость в удалении связанных с ними данных. Примеры удаления субъектов см. в статье Удаление субъектов Reliable Actors и данных их состояния.

Дальнейшие действия