9

우리는 주어진 간격 후에 새로운 메일 메시지를 MS Exchange를 폴링하는 EWS Managed API를 사용하고 있습니다. 폴링 호출 (PullSubscription.GetEvents())을 호출 할 때마다 - Microsoft API는 NetworkStream을 적절히 처리하지 못하여 비례하여 메모리가 증가합니다. 이전에 discussed here 이었지만 해결되지 않았습니다. ANTS Profiler를 사용하여 어떤 객체가 메모리에서 지속적으로 증가하는지 확인하고 문제를 격리 할 수있었습니다.참조 할 수없는 개체의 가비지 수집을 강제로 수행하는 방법?

이제 문제가 격리되었습니다. 참조가없는 외부 API에서 생성 된 NetworkStream을 처리 할 수있는 방법이 있습니까? GC.Collect()는 여전히 활성 참조가 있으므로이를 처리하지 않는 것처럼 보입니다. 매달린 참조를 정리하기 위해 우리는 무엇을 할 수 있습니까? 버그가있는 SDK를 강제로 정리하는 데 사용할 수있는 래퍼가 있습니까?

+0

나는 반사를 통해 참조를 얻을 수 있습니까? –

+0

라이브러리에서 분리 된 NetworkStream을 발견 한 곳에 게시 할 수 있습니까? GetEventsMethod를 찔러 보았지만 NetworkStream을 찾지 못했습니다. –

+0

@HenningKrause 또한 Daren Thomas의 접근 방식을 시도해 봤지만 건너 뛰기로 선택한 ExchangeService 및 SubscriptionBase 클래스의 내부에 대한 더 깊은 조사가 필요했습니다. 현재 Salvatore의 # 1을 따라 왔으며 MS와 함께 티켓을 열었습니다. 우리는 다음에 일어날 일을 볼 것입니다 ... – SliverNinja

답변

6

GC가 강제로 참조 된 객체의 메모리를 해제 할 방법이 없습니다!

우선이 버그에 대한 도움을 받으려면 Microsoft에 문의하는 것이 좋습니다.

둘째, "처분"에 대해 이야기하고 있습니까? 그들은 완전히 다른 두 가지입니다. (IDisposable 패턴, finalizers).

셋째, 이러한 개체를 참조하는 개체를 역 참조 할 수 있습니까?

넷째, 리플 렉터를 사용하여 문제를 일으키는 코드를 디 컴파일하고 참조 된 개체를 유지하는 필드에 도착할 수있는 방법을 이해하고 코드에서 리플렉션을 사용하여 비공개 필드에 액세스 할 수 있습니다 널에 두라. 아주 더러운 해킹이지만 다른 방법이 없다면 생각할 수있는 유일한 것입니다. 다른 방법으로 갈 수없는 경우에만 이것을하십시오.

+0

필드가 정적이지 않은 경우에도 4의 더러운 해킹이 작동합니다. 이는 "참조되지 않아야"하는 어떤 객체가 있다고 가정하지만, 문제가되는 객체를 살아있는 것으로 간접적으로 유지합니다. – svick

+0

물론이 방법은 모든 상황에서 작동하지만 다른 오브젝트를 참조 해제하지 않는 오브젝트를 역 참조 할 수 있다면 더러운 해킹없이이를 제안 할 수 있습니다. –

0

가장 쉬운 방법은 SDK를 자체 인터페이스 AppDomain으로 인터페이스하는 부분을 실행하고 AppDomain을 언로드 한 후입니다. 이로 인해 AppDomain에 할당 된 모든 메모리가 해제됩니다.

AppDomainMarshalByRef 개체 또는 serilizable으로 표시된 개체 만 교환 할 수 있으므로 작업을 프로젝트에 추가해야합니다.

이렇게하면 AppDomain에서 사용하는 메모리 양을 모니터링 할 수 있습니다. 따라서 AppDomain을 생성하고, 버그가있는 SDK를 실행하고, 메모리 사용량의 한계에 도달하면 언로드 할 수 있습니다.