저는 ESRI의 자체 .NET.NET Interop 어셈블리를 통해 ESRI의 ArcObjects COM 라이브러리를 사용하는 지리 데이터 처리를 위해 .NET 응용 프로그램을 개발 중입니다.GC가 수동으로 그렇게 할 때까지 ArcObjects COM 객체가 종료되지 않는 이유는 무엇입니까?
프로덕션 환경에서 실행 중일 때 프로세스 당 2GB의 메모리 제한에 도달하기 때문에 일부 작업 중에 프로세스가 중단 될 수 있습니다. (ArcObjects는 32 비트 라이브러리입니다.) 일부 처리 단계에서 많은 수의 임시 ArcObjects 지오메트리 개체를 만들 수 있기 때문입니다. FinalReleaseComObject
및 관련 도우미 메서드를 사용하여 이러한 개체를 수동으로 해제하더라도 메모리가 누수되고 결국 메모리가 부족합니다. 그러나 GC가 WaitForPendingFinalizers
을 호출하여 메모리를 해제하도록 강제 할 수 있으며 GC.Collect
및 FinalReleaseComObject
과 함께 정기적으로 호출하면 메모리 사용을 제어 할 수 있습니다. 그렇지 않으면 프로세스가 종료 될 때까지 (일반적으로 또는 비정상적으로) 많은 오브젝트가 메모리에 남아 있습니다.
첫 번째 질문 : 왜 ArcObjects COM 객체가 보유한 메모리가 즉시 해제되지 않습니까? 또는, 왜 GC가 충돌 된 프로세스가 충돌 이전에 해제 된 COM 개체를 마무리하고 메모리를 회수하는 대신 충돌을 허용합니까?
Windows 7 32 비트를 사용하여 개발하는 동안 응용 프로그램은 Windows 2008 64 비트에서 실행됩니다. 프로덕션 박스에서 프로세스가 중단 될 수 있지만 개발 상자에서는 중단되지 않습니다. 내가 로컬로 디버그 빌드와 함께 Visual Studio에서 일반적으로 실행하기 때문에 수도 있었지만, 나는 또한 디버거 (디버깅하지 않고 시작) 릴리스 빌드를 사용하여 그것을 시도했지만 그때까지도 근처에 많은 것을 사용하지 않았다고 생각 프로덕션 환경에서의 메모리와 충돌하지 않습니다.
두 번째 질문 : 이유가 무엇입니까?
편집 : 이전 실험에서 명시 적으로 호출했지만 GC.Collect
그 자체로는 충분하지 않습니다. 나는 이 뒤 따르는 GC.Collect
을 호출하는 유틸리티 메소드를 가지고 있으며, 모든 알고리즘 반복이 메모리 사용을 중단시킨 후에 그것을 호출한다.
RCW에 대해 알고 있지만 COM 개체가 보유한 메모리가 GC가 명시 적으로 실행 되더라도 해제되지 않습니다. 질문을 업데이트했습니다. – Gnat
@Gnat'GC.Collect()'가 GC를 실제로 실행하지 않기 때문에'GC.WaitForPendingFinalizers()'가 필요한 이유가 있습니다.GC가 수집주기를 수행하도록 요청했지만 GC가 다른 스레드에서 실행 중이며 많은 양의 부하로 인해 일정이 잡히지 않을 수 있습니다. 'GC.WaitForPendingFinalizers()'는 다음 수집 사이클이 끝날 때까지 기다려야합니다. 그러면 CPU가 해제되고 GC가 메모리 정리를 실행하고 완료 할 수 있습니다. – xxbbcc
@Gnat 만약 당신이'GC.WaitForPendingFinalizers()'를 호출 할 필요가 있는지 맞다면 (예기한다면), 응용 프로그램이 CPU에 부하를 걸면 기대할 것입니다. 로드가 많고 메모리가 많은 시나리오에서는 GC 스레드가 부족해질 수 있으며 시스템 (또는 프로세스)의 메모리가 부족할 수 있습니다. 내가 언급 한 그 오래된 프로젝트에서 나는 똑같이해야만했다. – xxbbcc