2012-05-29 2 views
0

최근 WPF 프로젝트에서 심각한 메모리 누수가 있음을 발견했습니다. 프로젝트를 단순화하면 로그인 양식과 기본 양식이 있습니다. 기본 폼에는 약 30 개의 사용자 컨트롤과 3 개의 버튼, 3 개의 버튼과 Infragistics DataGrid가있는 1 개의 사용자 컨트롤로 구성된 1 개의 사용자 컨트롤이 있습니다. 필자는 백그라운드 작업자를 사용하여 DataGrid에 대해서만 30 초마다 DB를 쿼리합니다.창 닫기 이벤트가 메모리 및 리소스를 해제하지 않습니다. WPF에서 메모리 누수를 해결하는 방법?

주 form.closed를 사용하여 주 양식을 로그 아웃 한 후 로그인 창을 다시 시작한 후에는 ANTS 메모리 프로필러가 측정 한 6-7MB가 증가 할 때마다 나타났습니다. 7. 등록되지 않은 이벤트 처리기가 있어도, 변수를 null로 설정하고 GC.Collect()라고하면 memeory 누출은 여전히 ​​동일합니다. 내 질문은 : 1. 왜 wpf 창을 닫으면 메모리와 리소스가 해제되지 않습니까? 나는 ANTs 프로파일 러에 의해 닫힌 윈도우 후에 많은 문자열 (대부분 GUI에서왔다)이 여전히 메모리에 있음을 볼 수있다. 2. 자원 이벤트 설정자가 정의한 이벤트를 등록 취소해야합니까? XAML에 선언 된 이벤트를 등록 취소해야합니까? 3. WPF memory leak에서 사람들은 GC.Collect()를 사용하지 않아야한다고 말했지만 조금 개선되었다고합니다. 우리는 그것을 사용할지 안할지?

답변

0

디버거에 침입 한 후 직접 실행 창에이를 입력 :

.load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll 

경로는 sos.dll 할 수는 다릅니다. 올바른 경로를 찾는 방법은 모듈 창에서 mscorwks.dll을 찾는 것입니다. 어디에서로드 된 sos.dll에 대한 올바른 경로입니다.

그런 다음이를 입력 : 도달 할 수없는 것을 보장합니다

System.GC.Collect() 

가 수집됩니다. 다음을 입력하십시오 :

!DumpHeap -type <some-type-name> 

그러면 주소가있는 기존 인스턴스의 테이블이 표시됩니다. 이 같은 인스턴스 살아 유지되고 있는지 확인할 수 있습니다

!gcroot <some-address> 

원래 상황에 따라 다르다 Daniel

0

로 대답했다. 당신이 당신의 통제에서 그것을 기능을 무시하고 수 있도록해야 할 것이다, 그래서 WPF에서 사용자 컨트롤은 본질적으로, 폐기하지 않습니다

http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx

하지만 당신의 포인트로, 당신은) (A GC.Collect를 수행해야합니다 SlimGG가 제안한대로 적어도 한 번.

대부분의 경우 가비지 수집기를 직접 호출하는 것은 사용자가 직접 제어하지 않고 처리하기 위해 대기중인 모든 개체에 대해 호출하기 때문에 나쁜 관행으로 간주됩니다.

+0

DependencyPropertyDescriptor.FromProperty ... AddValueChanged를 사용했지만 값이 변경되지 않아 코드가 메모리 누수가 발생하는 곳이 1 곳있었습니다. 그러나, 나는 여전히 다른 윈도우에서 메모리 누수를 발견했다. 나는 우리가 GC에게 전화하는 것에 동의한다.사용자 정의 컨트롤 안에 사용자 정의 컨트롤이 있으므로 수집하십시오. 감사. – user1424258

2

PictureBox 컨트롤에 WindowsFormsHost를 사용하는 동안 나는 비슷한 문제가있었습니다. WF PictureBox 컨트롤을 사용하는 WPF 창을 완전히 릴리스 할 수 없기 때문에 서브 윈 도우를 다시 열 때마다 정상적으로 ~ 10MB 증가했습니다. WPF 창을 닫을 때 WFH 개체를 null로 시작하기 때문에 문제가 해결되었습니다. 사용하는 경우 모든 WF 컨트롤을 지우십시오.

관련 문제