COM参照解放に関するメモ


COM参照解放をどうするか?

言うまでもないが.NETもメモリ管理を気にする必要あり。
IDisposableインターフェースを実装しており、Disposeメソッドが存在するものは
全てUsing等でライフタイム管理をする必要がある。
メンバ変数にする際はクラスはIDisposableインターフェースを実装し、
メンバ変数のライフタイム管理を行うのが適正。

COMはもっと厄介。
Excelを.NETで扱っていてexeが落ちない現象同様のことが発生する。

怠ると何が起きるか?
「保護されているメモリに読み取りまたは書き込みをしようとしました。」
Access Validation Errorなどが再現性不定で発生する。
メモリ関連例外の大半はCOM参照解放由来

どうしても解放できないものは元のオブジェクトのリークもあり得る。
触らぬCOMに祟りなし状態…。

× Marshal.ReleaseComObject一回呼び出し
↓↓↓
int cnt = 0;
while ((cnt = Marshal.ReleaseComObject()) < 1){}

上記やるぐらいならば
Marshal.FinalReleaseComObject

ComReleaserは一応参照カウンタを0にしてくれる
※Using使えるのでtry finaryする必要がないのが利点。

下記のような実装でMarshal.FinalReleaseComObjectでもよいが。
http://msdn.microsoft.com/en-us/magazine/cc163316.aspx

インスタンスが発生しうるすべての変数は解放されるべき。
COMインスタンスはライフタイム管理を考慮して実装設計されなければならない。

Tips:RCW共有のオブジェクトはObject.ReferenceEqualsで参照を同じくする。

http://forums.arcgis.com/threads/4298-What-s-Up-with-ComReleaser-Is-it-really-working
http://www.nicogis.blogspot.it/2010/07/rilascio-delle-risorse-in-ao.html

カテゴリー: 開発 タグ: , パーマリンク