[C#] 이벤트 처리기가 가비지 수집을 중지합니까?

다음 코드가있는 경우 :

MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass = null;

pClass는 가비지 수집됩니까? 아니면 이벤트가 발생할 때마다 이벤트가 계속 발생합니까? 가비지 수집을 허용하려면 다음을 수행해야합니까?

MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass.MyEvent -= MyFunction;
pClass = null;



답변

“pClass가 가비지 수집됩니까?”라는 특정 질문의 경우 : 이벤트 구독은 pClass (게시자)의 콜렉션에 영향을 미치지 않습니다.

일반적으로 GC (특히 대상)의 경우 : MyFunction이 정적인지 인스턴스 기반인지에 따라 다릅니다.

인스턴스 메소드에 대한 위임 (예 : 이벤트 구독)에는 인스턴스에 대한 참조가 포함됩니다. 예, 이벤트 구독은 GC를 방해합니다. 그러나 이벤트를 게시하는 객체 (위의 pClass)를 수집 할 수있게되면 문제가되지 않습니다.

이것은 단방향입니다. 즉, 우리가 가지고 있다면 :

publisher.SomeEvent += target.SomeHandler;

“publisher”는 “target”을 유지하지만 “target”은 “publisher”를 유지하지 않습니다.

pNo가 어쨌든 수집 될 경우 리스너를 구독 취소 할 필요가 없습니다. pClass는 (더 이상의 MyFunction와 인스턴스 이상) 수명이 긴 경우가 있으므로 그러나, 다음 pClass는 살아 해당 인스턴스를 유지할 수있는 것이 대상이 수집하려면 취소하는 것이 필요합니다.

그러나 이러한 이유로 정적 이벤트는 인스턴스 기반 핸들러와 함께 사용할 때 매우 위험합니다.


답변

예, pClass는 가비지 수집됩니다. 이벤트 구독은 pClass에 대한 참조가 있음을 의미하지 않습니다.

따라서 pClass를 가비지 수집하기 위해 핸들러를 분리하지 않아도됩니다.


답변

메모리 조각이 더 이상 참조되지 않는 순간 가비지 수집 대상이됩니다. 클래스의 인스턴스가 범위를 벗어나면 더 이상 프로그램에서 참조하지 않습니다. 더 이상 사용되지 않으므로 안전하게 수집 할 수 있습니다.

확실하지 않다면 무언가를 수집 할 것인지 스스로에게 다음과 같은 질문을하십시오. 이벤트 핸들러는 다른 방법이 아닌 객체 인스턴스에 의해 참조됩니다.


답변

pClass가비지 수집됩니다. 위의 코드 스 니펫을 다른 클래스 내에있을 경우 설정하지 않은 경우, 그 클래스의 인스턴스가 삭제되지 않을 수 있습니다 pClassnull.


답변