2014-07-07 2 views
0

우리의 응용 프로그램은 일부 모듈을로드하는 AppDomain을 설정합니다. 이러한 모듈 중 하나는 H5 파일과 상호 작용하기 위해 레거시 혼합 모드 DLL을 사용하고 있습니다. 문제는 혼합 모드 DLL을로드하자마자 핸들이 새 AppDomain과 응용 프로그램이 시작될 때 만들어 졌던 원래 AppDomain 모두에 배치된다는 것입니다.모든 모드로로드 된 혼합 모드 어셈블리

새 AppDomain의 핸들은 AppDomain을 언로드 할 때 자연스럽게 사라지지만 원래 AppDomain의 핸들은 유지되고 고정됩니다. 이로 인해 관리되는 힙이 조각납니다.

이 동작을 설명하는 혼합 모드 소스 코드에서 아무 것도 찾을 수 없습니다. H5Utils::errorStack_.c_str() 네이티브 정적 문자열입니다

H5Utils::throwError(String^ message) { 
    String^ stackStr = gcnew String(H5Utils::errorStack_.c_str()); 
    String^ myMessage = message + "\n\nError stack: " + stackStr; 
    throw gcnew H5IOError(myMessage); 
} 

: 의심스러운있는 유일한 방법은 기본 정적 문자열을 사용하는 다음 호출입니다. 그러나이 메서드는 절대로 호출되지 않으며 모듈은 혼합 모드 DLL이로드 될 때 즉시 두 AppDomains에로드됩니다.

핸들이 두 AppDomains에서 모두 생성되는 이유를 알고 있습니까?

+0

글쎄, 그렇지 않아. ! gchandles 명령 [SOS 디버거 확장] (http://msdn.microsoft.com/en-us/library/bb190764%28v=vs.110%29.aspx)이 필요합니다. 그것. –

+0

감사합니다. 그러나 이것이 어떻게 도움이 될지 모르겠습니다. 나는 이미 누출 된 손잡이가 있다는 것을 알고있다. 이 문제가 발생하는 이유는 원래 AppDomain과 내가 만든 혼합 모드 모듈을로드하기 위해 만든 AppDomain에서 핸들이 설정되는 이유입니다. –

+0

이 핸들이 살아있는 개체의 유형을 모르는 경우 그것이 어디서 그리고 왜 만들어 졌는지 알 수 없습니다. –

답변

1

이렇게 나는 더 많은 것을 파헤 쳤고 답을 찾았습니다. 누군가가 같은 문제에 부딪혔을 때 제 대답을 생각했습니다.

모듈이 두 AppDomains로로드되는 이유는 고유 전역 값과 정적 멤버 값의 사용 때문입니다. 이 값은 네이티브 힙에 할당되기 때문에 실제로 이해할 수 있습니다.이 모듈을 둘 이상의 AppDomain에서 사용하면이 값을 계속 공유 할 확률이 높습니다.

문제는 지속적으로 AppDomains를 만들고 파괴하고 실행중인 프로세스 AppDomain에 처음 추가되는 참조가 고정되어있어 고정되기 때문에 이러한 종류의 리소스를로드하는 경우입니다. 이렇게하면 관리 힙이 조각 나고 장기 실행 프로세스가 메모리를 소비하기 시작합니다.

이 문제를 해결하기 위해 고유 형식의 전역에 추가해야하는 __declspec(appdomain)이 추가되어 모듈을 만든 AppDomain에만 있어야합니다. /clr:pure을 설정하면이 선언이됩니다. 이것에 대한 대부분의 설명은 msdn's help on appdomain

#include입니다. 예를 들어 #include <string>은 모듈이 AppDomains간에 공유되도록하며 #include <stdio.h>은 그렇지 않습니다.