2009-06-30 2 views
1

많은 COM 개체 (Outlook 메일, Outlook 폴더 등)를 만드는 Outlook Addin에서 작업하고 있습니다. 내 이해는 이러한 개체는 COM 개체이므로 CLR은 이러한 개체에서 메모리를 해제하지 않으며 이러한 개체에서 메모리를 해제해야합니다. 이러한 개체에서 메모리를 해제하려면 사용해야합니다.CLR이 COM 개체에서 메모리를 해제합니까?

마샬링. ReleaseComObject (Object);

불행히도 이것은 작동하지 않는 것 같습니다. 그런 다음 Marshal.ReleaseComObject (Object) 다음에 GC.Collect() 문을 넣었습니다.이 작업이 끝났습니다. 그 후 아무런 관련 예외가 발생하지 않았습니다. 제 질문은 CLR이 COM 개체에서 메모리를 relase 할 수 있다면 왜 자체적으로 그것을 수행하지 않는 것입니까? GC.Collect() 문이 내 경우에 어떻게 작동하는지 이해할 수 없습니다.

답변

7

.COM과 COM을 사용하려면 Runtime Callable Wrapper을 잘 이해하고 있어야합니다. 기본적으로 COM 객체에 대한 참조 인 .Net 코드에있는 모든 것이 실제로 RCW에 대한 참조입니다. RCW는 기본 COM 개체에 대한 참조 횟수를 계산하여 참조 횟수를 관리하며, 참조 횟수가 0으로 떨어지면 기본 개체에 Release (한 번)을 호출합니다. RCW가 실행되는 동안 COM 개체에 대한 단일 참조가 유지됩니다.

ReleaseComObject API는 RCW의 참조 횟수를 1 줄입니다. RCW의 참조 횟수를 0으로 설정하면 RCW가 COM 개체에서 Release을 호출합니다. 그렇지 않은 경우 RCW가 호출합니다. FinalReleaseComObject은 RCW의 참조 카운트가 0이되도록합니다 (따라서 RCW는 Release을 호출합니다). RCW에서 다른 참조가 미흡했을 경우 위험 할 수 있습니다.

"일반적으로"RCW에 대한 참조는 참조가있는 개체가 가비지 수집 될 때 관리됩니다. 이렇게하면 가비지 수집을 강제했을 때 COM 개체가 해제 된 것을 알 수 있습니다. RCW의 작동 방식에 대해 우리가 알고있는 것과 합쳐서 RCW에 ReleaseComObject을 호출하여 Release을 호출해야하는 다른 참조가 있다는 것을 알 수 있습니다.

ReleaseComObject은 .Net 런타임에서 끝나는 일종의 호출이며 생성 된 모든 참조를 관리하는 데 신중해야합니다. 생성 된 참조 중 일부는 "암시 적"참조입니다. 이러한 참조는 호출 한 참조를 반환하는 속성을 호출하는 등의 작업을 수행하기 때문에 발생합니다. 이 같은 수행 할 때이 때때로는 "너무 많은 점"문제로에 대해 참조된다

object.foo.blah.baz.something() 

은 "foo는", "ㅋ"와 "바즈을"일부 COM 개체에 대한 모든 참조 어딘가에 아마 그 당신은 생각할 필요가 있습니다.

+1

이제 COM이 마음에 들지 않는 이유를 기억합니다. – OregonGhost

+1

하. COM에서 오는이 절름발이 .NET 구현은 .Net을 좋아하지 않는 이유입니다! –

+0

때때로, 나는 정말로 내가 의견을 downvote 할 수 있었 더라면 좋겠다고 생각한다. 그러나 헤이, 나는 그것을 다른 사람에게 upvoting하는 것으로 보답했다 :) – Aamir

0

Marshal.ReleaseComObject 뒤에 메모리를 할당하려고 했습니까? 가비지 컬렉터는 자신의 의지에 따라 실행되기 때문에 메모리가 할당 될 때뿐만 아니라 (GC.Collect를 호출하지 않는 한) 실행해야한다고 생각할 때가 아니라 일반적으로 의미합니다.

지금까지 COM 개체를 자동으로 해제하는 데 아무런 문제가 없었으며 COM 서버를 즉시 종료하려는 경우에만 Marshal.ReleaseComObject를 호출했습니다.