문제

.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();
    }

예상대로 '0'을 콘솔에 작성하고 씁니다. 그러나 항상 작동하는지 궁금합니다.

누군가가 현장 뒤에서 무슨 일이 일어나고 있는지 알고 있습니까?

도움이 되었습니까?

해결책

이를 부활이라고하며 합법적입니다. ".NET Object Resurrection"(및 이와 같은 용어)에 대한 Google은 다음과 같은 것들을 찾을 수 있습니다.

부활 및 .NET 쓰레기 수집기

물체 부활

이 좀비 물체가 돌아와서 뇌나 무언가를 먹으려 고하지 않도록하십시오. 모든 Necromancy와 마찬가지로 이것은 위험한 것입니다. (주로 클래스 계층 구조에서 최종화기가 더 높은 수준의 필수 리소스를 공개 할 수 있기 때문에. 또한 전화를 걸지 않는 한 객체가 "참조되지 않은"경우 파이널 라이저가 두 번째로 실행되지 않을 것입니다. GC.ReRegisterForFinalize.)

다른 팁

첫 번째 가비지 컬렉션이 인스턴스를 수집하지 않기 때문에 작동합니다. 인스턴스가 최종화기를 실행하도록 예약합니다. 그런 다음 Finalizer는 인스턴스에 새로운 루트를 생성하므로 다음 컬렉션이 발생하면 인스턴스가 실제로 루팅되어 수집을위한 것이 아닙니다.

당신은이 힘든 것에 대해 매우 조심해야합니다. 파이널 라이저가 객체에 배치되도록하는 데 사용되는 경우, 일회용 패턴에 배치 된 인스턴스가 배치 된 후 사용되면 대상이있는 인스턴스를 던져야한다고 말하면 실제로 프로토콜을 위반합니다.

쓰레기 수집가는 객체를 세 그룹으로 나눕니다.

  1. 마지막으로 살아있는 것들은 마침내 마침내 기준이 최종 대기열 외부에 존재했기 때문에;
  2. 근본 원인이 존재하지 않기 때문에 삭제 해야하는 것;
  3. 뿌리가 붙은 참조가 최종 대기열에 존재하지만 다른 곳은 없기 때문에 마무리해야 할 것입니다.
근처의 참조가 없으면 객체를 삭제할 수 없습니다. 마무리는 삭제되기 전에 뚜렷한 단계입니다. 객체는 최종화를 위해 등록되지만 직접 또는 간접적으로 참조하는 모든 객체는 결실로부터 보호되지만 최종화로부터 보호되지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top