Ciclo de vida do ator, libertação de lixo automática e eliminação manual
Um ator é ativado na primeira vez que é feita uma chamada para qualquer um dos seus métodos. Um ator é desativado (lixo recolhido pelo runtime Atores) se não for utilizado durante um período de tempo configurável. Um ator e o respetivo estado também podem ser eliminados manualmente em qualquer altura.
Ativação de ator
Quando um ator é ativado, ocorre o seguinte:
- Quando uma chamada chega para um ator e uma ainda não está ativa, é criado um novo ator.
- O estado do ator é carregado se estiver a manter o estado.
- O
OnActivateAsync
método (C#) ouonActivateAsync
(Java) (que pode ser substituído na implementação do ator) é chamado. - O ator é agora considerado ativo.
Desativação do ator
Quando um ator é desativado, ocorre o seguinte:
- Quando um ator não é utilizado durante algum tempo, é removido da tabela Active Actors.
- O
OnDeactivateAsync
método (C#) ouonDeactivateAsync
(Java) (que pode ser substituído na implementação do ator) é chamado. Isto limpa todos os temporizadores do ator. As operações de ator, como alterações de estado, não devem ser chamadas a partir deste método.
Dica
O runtime dos Fabric Actors emite alguns eventos relacionados com a ativação e desativação de ator. São úteis nos diagnósticos e na monitorização do desempenho.
Libertação da memória do ator
Quando um ator é desativado, as referências ao objeto de ator são libertadas e podem ser recolhidas da memória normalmente pelo runtime de linguagem comum (CLR) ou pelo recoletor de lixo da máquina virtual Java (JVM). A libertação da memória só limpa o objeto de ator; não remove o estado armazenado no Gestor de Estado do ator. Da próxima vez que o ator for ativado, é criado um novo objeto de ator e o respetivo estado é restaurado.
O que conta como "a ser utilizado" para fins de desativação e libertação da memória?
- Receber uma chamada
IRemindable.ReceiveReminderAsync
método que está a ser invocado (aplicável apenas se o ator utilizar lembretes)
Nota
se o ator utilizar temporizadores e a chamada de retorno do temporizador for invocada, não conta como "a ser utilizado".
Antes de avançarmos para os detalhes da desativação, é importante definir os seguintes termos:
- Intervalo de análise. Este é o intervalo em que o runtime actors analisa a respetiva tabela active actors para atores que podem ser desativados e libertação da memória. O valor predefinido para este valor é de 1 minuto.
- Tempo limite de inatividade. Esta é a quantidade de tempo que um ator precisa para permanecer inutilizado (inativo) antes de poder ser desativado e libertação da memória. O valor predefinido para este valor é de 60 minutos.
Normalmente, não precisa de alterar estas predefinições. No entanto, se necessário, estes intervalos podem ser alterados ao ActorServiceSettings
registar o Serviço de Ator:
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);
}
}
Para cada ator ativo, o runtime do ator controla a quantidade de tempo durante o qual esteve inativo (ou seja, não foi utilizado). O runtime do ator verifica cada um dos atores ScanIntervalInSeconds
para ver se pode ser lixo recolhido e marca-o se estiver inativo para IdleTimeoutInSeconds
.
Sempre que um ator é utilizado, o tempo de inatividade é reposto para 0. Depois disso, o ator só pode ser libertado do lixo se permanecer novamente inativo para IdleTimeoutInSeconds
. Lembre-se de que um ator é considerado como sendo utilizado se for executado um método de interface de ator ou uma chamada de retorno de lembretes de ator. Um ator não é considerado como sendo utilizado se a chamada de retorno do temporizador for executada.
O diagrama seguinte mostra o ciclo de vida de um único ator para ilustrar estes conceitos.
O exemplo mostra o impacto das chamadas de método de ator, lembretes e temporizadores na duração deste ator. Vale a pena mencionar os seguintes pontos sobre o exemplo:
- ScanInterval e IdleTimeout estão definidos como 5 e 10, respetivamente. (As unidades não são importantes aqui, uma vez que o nosso objetivo é apenas ilustrar o conceito.)
- A análise para que os atores sejam recolhidos da memória ocorre em T=0,5,10,15,20,25, conforme definido pelo intervalo de análise de 5.
- Um temporizador periódico é acionado em T=4,8,12,16,20,24 e a chamada de retorno é executada. Não afeta o tempo de inatividade do ator.
- Uma chamada de método de ator em T=7 repõe o tempo de inatividade para 0 e atrasa a libertação da memória do ator.
- Uma chamada de retorno de lembrete de ator é executada em T=14 e atrasa ainda mais a libertação da memória do ator.
- Durante a análise da libertação da memória em T=25, o tempo de inatividade do ator excede finalmente o tempo limite de inatividade de 10 e o ator é libertado da memória.
Um ator nunca será libertado do lixo enquanto executa um dos seus métodos, independentemente do tempo gasto na execução desse método. Conforme mencionado anteriormente, a execução de métodos de interface de ator e chamadas de retorno de lembretes impede a libertação da memória ao repor o tempo de inatividade do ator para 0. A execução de chamadas de retorno de temporizador não repõe o tempo de inatividade para 0. No entanto, a libertação da memória do ator é adiada até que a chamada de retorno do temporizador tenha concluído a execução.
Eliminar manualmente os atores e o respetivo estado
A libertação da memória de atores desativados só limpa o objeto de ator, mas não remove os dados armazenados no State Manager de um ator. Quando um ator é reativado, os respetivos dados são novamente disponibilizados através do Gestor de Estado. Nos casos em que os atores armazenam dados no State Manager e são desativados, mas nunca são reativados, poderá ser necessário limpar os respetivos dados. Para obter exemplos de como eliminar atores, leia eliminar atores e o respetivo estado.