우리는 수백 개의 클라이언트에 WinForms 응용 프로그램을 설치했습니다. 일부에서는 OutOfMemoryException이 결국 throw 될 때까지 메모리 사용이 명백한 이유없이 시간이 지남에 따라 올라 가기 시작합니다.Finalizer 스레드 오작동으로 인한 메모리 누수 문제 해결
우리는 DebugDiag Collection and Analysis를 사용하여 문제를 이해하려고했습니다. 우리는 these warnings을 얻었습니다.
마무리 작업을위한 거대한 대기열 개체 (42K)가 있었기 때문에 처음에는 Finalizer 스레드를 살펴 보았습니다.
ntdll!KiFastSystemCallRet
ntdll!NtWaitForSingleObject+c
KERNELBASE!WaitForSingleObjectEx+98
kernel32!WaitForSingleObjectExImplementation+75
clr!CLREventBase::Reset+17e
clr!CLREventBase::Reset+1c6
clr!CLREventBase::WaitEx+152
clr!FinalizerThread::WaitForFinalizerEvent+38
clr!FinalizerThread::FinalizerThreadWorker+5f
clr!Thread::DoExtraWorkForFinalizer+1b1
clr!Thread::DoExtraWorkForFinalizer+234
clr!Thread::DoExtraWorkForFinalizer+5f8
[[DebuggerU2MCatchHandlerFrame]]
clr!ManagedThreadBase::FinalizerBase+33
clr!FinalizerThread::FinalizerThreadStart+d4
clr!Thread::intermediateThreadProc+55
kernel32!BaseThreadInitThunk+e
ntdll!__RtlUserThreadStart+70
ntdll!_RtlUserThreadStart+1b
같은 과정을 다섯 시간 후에, 그리고 DebugDiag에 의해 표시되는 경고 these 같습니다이는 호출 스택 덤프시처럼 보였다 방법이다.
그래서, 마무리 작업 준비가 완료되면 메모리가 거의 두 배로 누출되었습니다. Finalizer 스레드 호출 스택은 이전 스레드 호출 스택과 동일합니다. 사실, 문제는 차단 된 최종 스레드에있는 것처럼 보이므로 GC가 사용되지 않는 객체를 제거 할 수 없습니다.
우리는 코드에 파이널 라이저를 사용하지 않습니다. 파이널 라이저 스레드가 수행 할 블로킹 작업은 무엇입니까? 어떻게 책임질 수있는 외부 모듈이 있는지, 그리고 어떤 모듈이 있는지 알아낼 수 있습니까?
몇 가지 추가 정보 : 우리는 .NET Framework 4.0을 사용 중이며 우리의 응용 프로그램은 x86 용으로 컴파일됩니다. 이 문제는 Windows 7+ SO에서 재현 될 가능성이 높지만 XP는 더 잘 작동하는 것처럼 보입니다.
어디서 볼지에 대한 도움이나 힌트를 주시면 감사하겠습니다.
꽤 높지만 finalizer 스레드 스택 추적은 완전히 정상입니다. 사용되는 메모리의 양이 너무 많아서 메모리가 부족한 프로그램이 아닙니다. GC가 자주 실행되는지 확인하십시오. –
우리는 약 5 시간의 실행을 말합니다. 우리의 응용 프로그램은 다시 시작하지 않고 몇 달 동안 작동 할 것으로 예상되며, 그 때 OutOfMemory가 발생합니다. – armarru