2009-06-30 11 views
1

私は多くのCOMオブジェクト(Outlookメール、Outlookフォルダなど)を作成するOutlook Addinで作業しています。これらのオブジェクトはCOMオブジェクトなので、CLRはこれらのオブジェクトからメモリを解放しないため、これらのオブジェクトからメモリを解放する必要があります。これらのオブジェクトからメモリを解放するにはCLRはCOMオブジェクトからメモリを解放しますか?

マーシャルを使用します。 ReleaseComObject(オブジェクト);

残念ながら、これはうまくいかないようです。その後、Marshal.ReleaseComObject(Object)の後にGC.Collect()ステートメントを置いて、これがうまくいきました。 私の質問は、CLRがCOMオブジェクトからメモリを解放できるのであれば、なぜそれがそれ自身でそれをしないのかです。 GC.Collect()ステートメントが私の場合にどのように働いたのかが分からなければ。

答えて

7

.COMでCOMを使用するには、Runtime Callable Wrapperをよく理解している必要があります。基本的には、COMオブジェクトへの参照である.Netコード内のすべてのものは、実際にはRCWへの参照です。 RCWは、基になるCOMオブジェクトの参照カウントを管理することによって参照カウントを管理し、参照カウントが0になると基底オブジェクトのRelease(1回)を呼び出します。 RCWはライブ中にCOMオブジェクトの単一参照を保持します。

ReleaseComObject APIは、RCWの参照カウントを1減らします。これにより、RCWの参照カウントが0になると、RCWはReleaseをCOMオブジェクトに呼び出します。 FinalReleaseComObjectもあり、RCWの参照カウントが0になるため(RCWはReleaseになります)、他の参照がRCWに残っているとエラーが発生する場合は危険です。

RCWの参照は、参照を持つオブジェクトがガベージコレクションされたときに管理されます。ガベージコレクションを強制したときにCOMオブジェクトが解放された理由を説明します。これは、RCWの仕組みについて知っていることと相まって、ReleaseにするためにReleaseComObjectを呼び出すために必要となるRCWに関する他の参照があることを示しています。

ReleaseComObjectを呼び出すと、.Netランタイムの周りで実行されるようになり、作成されたすべての参照を管理するために細心の注意が必要です。作成される参照の中には「暗黙の」参照があります。これらの参照は、呼び出す参照を返すプロパティを呼び出すようにするために起こります。

object.foo.blah.baz.something() 

「foo」という、「何とか」と「バズ」おそらくどこかのCOMオブジェクトへのすべての参照ということです。これは、時々、あなたはこのようなものがないとき、「あまりにも多くのドット」の問題として参照されますあなたは考える必要があります。

+1

今私はCOMが気に入らない理由を覚えています。 – OregonGhost

+1

Ha。 COMから来て、この不自由な.Net実装は好きではない理由です.Net! –

+0

時には、私は本当に私がコメントをdownvoteできることを望みますが、ねえ、私は他の1つupvotingでそれを補償している:) – Aamir

0

Marshal.ReleaseComObjectの後にメモリを割り当てようとしましたか?ガベージコレクタは独自の意志で実行されるため、通常はメモリが割り当てられているときだけでなく、GC.Collectを呼び出さない限り、実行する必要があるとは限りません。

これまでCOMオブジェクトを自動的に解放することに何の問題もなく、COMサーバーをすぐにシャットダウンする必要がある場合にのみMarshal.ReleaseComObjectを呼び出しました。

関連する問題