2011-02-26 2 views
5

람다를 EventHandler로 사용하는 유효한 방법입니까? 처리기가 올바르게 제거되었고 가비지 수집기가이를 정리해야하는 것으로 보입니다. 그러나, 나는 다른 사람이 이런 식으로하는 것을 보지 못했기 때문에, 나는 두 번 확인하는 것이 더 좋을 것이라고 생각했다.가비지 수집됩니까?

동일한 줄에 따라 실제로 가비지 수집 중인지 여부를 테스트하는 데 사용할 수있는 가장 좋은 도구는 무엇입니까?

DispatcherTimer timer = new DispatcherTimer(); 
timer.Interval = TimeSpan.FromSeconds(10); 

EventHandler callback = null; 
callback = (s, e) => 
    { 
     timer.Stop(); 
     timer.Tick -= callback; 
    }; 

timer.Tick += callback; 
timer.Start(); 
+0

관심있는 사람들에게 위의 코드를 1M 번 실행 한 테스트를 만들었습니다. 메모리 사용은 전체적으로 유지되었습니다. – herbrandson

답변

3

예, 콜백은 한 번 실행 된 후에 가비지 수집 대상이됩니다. 이는 처리기를 한 번만 실행하기 위해 이벤트에 가입하는 합리적인 방법입니다.

그것은 대리인이 쓰레기 수집됩니다을 증명 에 힘든 - 객체가 캡처 된 변수를 저장하는 데 사용 callbacktimer 쓰레기 수집 될 것으로 참으로 또는, 틀림없이 ... 당신은 정말 종료자를 넣고 싶어 거기에 (물론 가비지 콜렉션 자체에 영향을 미친다.),하지만 당신은 코드를 생성 할 수 없다.

4

DispatcherTimer는 Dispatcher 클래스에 의해 유지되며 활성화 된 타이머에 대한 참조를 저장하는 내부적으로 List<DispatcherTimer>을 유지합니다. 타이머를 Stop() 시키 자마자 객체는 그 목록에서 제거되어 추가 참조를 저장하지 않으면 가비지 콜렉션을 사용할 수있게됩니다. 이 경우 타이머 참조는 지역 변수가 아닙니다.

람다를 구현하는 자동 생성 클래스에서 finalizer를 얻을 수 없습니다. 다음으로 가장 좋은 방법은이 코드를 10 억 번 실행하는 것입니다. 가출 회원과 OOM을 얻지 못하면 분명히 누출되지 않습니다. Interval을 짧게 만들어서 크리스마스 때까지 걸리지 않도록하십시오. 15 밀리 초가 좋습니다. Timer를 사용하여 메서드를 호출하면 동시에 너무 많은 활성 타이머를 가져 오지 않고 Dispatcher가 작업을 수행 할 수 있습니다.

관련 문제