메모리 사용에있어 애플리케이션을 최적화해야합니다. 그래서 나는 .net 성능 프로파일 러를 사용했습니다 ... 하지만 내 응용 프로그램의 일부 참조는 여전히 살아 있으며 수집을 강제하더라도 GC로 수집되지 않습니다.마무리 작업 핸들이 메모리에 남아 있습니다. 이 참조를 제거하는 방법?
살아있는 참조는 "마무리 처리"유형입니다. 이런 종류의 참조를 제거하려면 어떻게 해야할지 모르겠다 .... 도와주세요.
메모리 사용에있어 애플리케이션을 최적화해야합니다. 그래서 나는 .net 성능 프로파일 러를 사용했습니다 ... 하지만 내 응용 프로그램의 일부 참조는 여전히 살아 있으며 수집을 강제하더라도 GC로 수집되지 않습니다.마무리 작업 핸들이 메모리에 남아 있습니다. 이 참조를 제거하는 방법?
살아있는 참조는 "마무리 처리"유형입니다. 이런 종류의 참조를 제거하려면 어떻게 해야할지 모르겠다 .... 도와주세요.
이것은 메모리 누출 AMProLibrary의 저자 (들)의 일부에 불과 조잡 코딩은 없다.
관찰 한대로 프로파일 러는 참조 된 개체의 유형이 "Finalization Handle"임을 알려줍니다. 그게 finalizer 큐에서 오는 것입니다. finalizer 큐는 .NET 가비지 수집기가 finalizer 메서드를 구현하는 모든 개체를 저장하는 데 사용하는 큐입니다. 파이널 라이저는 가비지 콜렉션 중에 관리되지 않는 리소스가 올바르게 릴리스되도록하는 데 사용되는 메커니즘입니다. 관리되지 않는 리소스가 포함 된 개체는 Finalize
메서드를 포함하여 IDisposable
패턴을 구현합니다.이 메서드는 관리되지 않는 리소스가 해제되는 곳입니다. 가비지 수집기가 "finalizable"객체를 처리하면 (객체 헤더의 비트 값으로 표시됨) 최종 객체 대기열로 이동합니다. 수집하는 동안 GC는 종료 자 큐를 반복하고 각각의 객체에 대해 Finalize
메서드를 호출합니다.
분명히 라이브러리 작성자가 수행하지 못한 것은 Dispose
메서드에서 GC.SuppressFinalize()
으로 전화하는 것입니다. 이것은 일반적으로 객체의 헤더에서 "finalizable"비트를 지움으로써 객체를 finalizer 큐에서 제거하고 Finalize
메소드를 호출 할 필요가 없음을 나타냅니다.
테스트 목적으로 GC.WaitForPendingFinalizers
함수를 호출하여 종료기를 강제 실행할 수 있습니다. 예 :
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.GC.Collect();
그러나 실제로 프로덕션 응용 프로그램에서는 이와 같은 코드를 사용하면 안됩니다. 컬렉션을 강제하는 것은 거의 의미가 없습니다. 이것은 위에서 언급 한 가설의 타당성을 증명할뿐입니다.
일반적으로 관리되지 않는 리소스를 해제하기 위해 파이널 라이저를 사용해서는 안됩니다. IDisposable
을 구현하는 모든 개체는 수동으로 Dispose
메서드를 호출하거나 블록 범위가 종료 될 때 Dispose
을 자동으로 호출하는 using
블록에서 해당 벡터를 래핑하여 코드에서 명시 적으로 처리해야합니다.
"Never"는 분명히 정상이 아닙니다. 라이브러리가 이러한 객체를 끊임없이 생성하는 것이 아니라면 finalizer 스레드를 잘 살펴 봐야합니다. 교착 상태 일 수 있습니다. 관리되지 않는 디버깅을 활성화하고 디버그> Windows> 스레드 디버거 화면을 사용하여 찾습니다. –