Pergunta

É legal para escrever o seguinte no .net?

   public class A
    {
        public int i = 0;
        ~A()
        {
            Aref = this;
        }
    }


    public static A Aref;
    static void Main(string[] args)
    {
        Aref = new A();
        int gen = GC.GetGeneration(Aref);
        Aref = null;
        GC.Collect(gen, GCCollectionMode.Forced);
        GC.WaitForPendingFinalizers();
        Console.WriteLine(Aref.i);
        Console.ReadLine();
    }

Ele trabalha e escreve '0' para o console como esperado, mas eu estou querendo saber se ele está garantido para sempre trabalho.

Alguém sabe o que está acontecendo por trás da cena?

Foi útil?

Solução

É chamado de ressurreição, e é legal. Google por "ressurreição objeto .net" (e termos como ele) e você encontrará coisas como:

Ressurreição eo lixo .NET coletor

objeto Ressurreição

Apenas certifique-se esses objetos zumbis não voltar e tentar comer o seu cérebro ou algo assim. Como todos necromancia, isso é coisa perigosa. (Principalmente porque os finalizadores mais acima na hierarquia de classes pode ter liberado algum recurso essencial. Além disso, note que a finalizador não será executada uma segunda vez se o objeto fica "sem referência", a menos que você chamar GC.ReRegisterForFinalize.)

Outras dicas

Ele funciona porque a primeira coleta de lixo não recolhe a instância. É apenas agenda a instância ter sua corrida finalizador. O finalizador, em seguida, cria uma nova raiz para a instância, por isso quando a próxima coleção acontece a instância é realmente enraizados e, portanto, não se para a coleção.

Você deve ter muito cuidado com este difícil. Se o finalizador é usado para certificar-se de um objeto é descartado, isso realmente viola o protocolo porque os padrões descartáveis ??diz que uma instância dispostos deve lançar uma ObjectDisposedException se for utilizado depois de ter sido descartado.

As clivagens colector de lixo objetos em três grupos:

  1. Aqueles que estão ainda vivos, porque na última verificação de referência enraizada existia fora da fila de finalização;
  2. Aqueles que necessidade de ser excluído, porque nenhuma referência enraizada existe em qualquer lugar;
  3. Aqueles que precisam de ser finalizado, porque existe uma referência enraizada na fila de finalização, mas em nenhum outro
. Objetos não podem ser excluídos a menos que não há qualquer referência enraizadas. Finalização é uma fase distinta antes de eliminação; nota que, enquanto um objeto é registrado para a finalização, todos os objetos faz referência direta ou indiretamente serão protegidos contra exclusão, mas não de finalização.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top