2009-05-29 2 views
5

:가비지 수집기가 이벤트에 가입 된 객체를 지 웁니까? 나는 다음과 같은 경우

public class Test 
{ 
    public static void Main() 
    { 
     List<Person> persons = new List<Person> { new Person() }; 

     persons[0].Sneezing += new EventHandler(Person_Sneezing); 

     persons = null; 
    } 

    public static void Person_Sneezing(object sender, EventArgs e) 
    { 
     (sender as Person).CoverFace(); 
    } 
} 

가 대리자를 재채기 것하면 Person_Sneezing 방법에 대한 참조가 아니면이 GC에 의해 수집받을 않기 때문에 사람에 있던 사람이 [0] 여전히 메모리에 존재합니까?

답변

8

GC로 수집합니다.

  1. 값 강한 GC에 뿌리를 둔 값은
  2. 코너 케이스 또는 두 개의 난을 처리
  3. 스택에 ... 객체가 직접 또는 간접적으로 참조해야합니다 메모리에 보관하려면 지금 생각하지 마라.

사람 [0]의 물건에는 그렇지 않다. 그래서 그것은 수집 될 것입니다.

당연히 Person()의 생성자가 ThreadLocalStorage에 자신을 추가하는 것처럼 웃기는 일을하지 않는다고 가정합니다.

1

더 많은 답변을 얻으려면보다 현실적인 예에주의해야합니다.

응용 프로그램에 프로그램이 실행되는 동안 살아남은 메인 윈도우가 있고 메인 윈도우의 이벤트에 메소드를 참여시키는 "수명이 짧은"객체를 자주 만드는 경우 해당 이벤트의 객체를 삭제해야합니다 당신이 더 이상 필요하지 않을 때, 그렇지 않으면 그 객체들은 "단명"하지 않을 것이기 때문에, 그들은 메인 윈도우만큼 오래 지속될 것입니다, 즉 사용자가 응용 프로그램을 닫을 때까지 살아남을 것입니다. 효과적인 결과는 메모리 누수와 동일합니다.

수명이 짧은 개체의 클래스를 IDisposable으로 구현하면 Dispose의 이벤트를 사용하지 않도록 설정 한 다음 개체를 삭제하려고 할 때 처리해야합니다.

6

중간에 있습니다. 다른 방법으로 인 경우 메모리 누수가 발생합니다.

public class Test { public void HookupStuff() { List<Person> persons = new List<Person> { new Person() }; this.EventHappened += new EventHandler(persons[0].SomeMethod); // persons[0].Sneezing += new EventHandler(Person_Sneezing); persons = null; } } 

지금 persons[0] 부모 클래스가에 방법에 대한 참조를 가지고 있기 때문에 당신이 persons을 널링에도 불구하고, 곁에합니다 :이처럼 보였다 경우입니다
.

+0

누출이라고 부를 수 있습니까? 테스트가 진행되면 사람도 마찬가지입니다 [0]. –

+0

물론, 모든 것이 사라집니다 * 최악의 경우, 응용 프로그램이 종료 될 때 모두 사라집니다! 나는 그것이 사라질 것이라고 생각할 때 그것이 사라지지 않을 때 그것을 누출이라고 부를 것이다. – mquander

+0

(또한 사람 [0]에 대한 다른 참조를 작성하지 않았다면 다시 돌려받을 수 없으므로 기본적으로 아무것도 유출되지 않습니다.) – mquander

관련 문제