- PR -

COM Interopのリークの可能性について

1
投稿者投稿内容
ryuuji
ベテラン
会議室デビュー日: 2003/07/10
投稿数: 53
お住まい・勤務地: 東京都
投稿日時: 2004-10-04 11:52
現在、プロジェクトで.NETプロダクトを含むシステムでリークが発生しており調査の一環としてWebなど調べてみたところMSDNのブログで以下のような記事を見つけました。

http://blogs.msdn.com/cbrumme/archive/2004/02/02/66219.aspx

私には内容が難しく完全に理解できていないのですが、.NETクライアント(STA)からCOM(MTA)を呼び出すと、スレッドが暗黙的にMTAに再配置され、その時リークが起こり得ると書いてあります(あると思う...)。

そこでアウトプロセスの空っぽのメソッドを持つCOMをVC++6で作成して.NETのWindows Formアプリケーション(STA)から5秒おきに10スレッド起こして呼び出し、呼出し完了後にSystem.GC.Collect()で全世代を強制回収するというテストプログラムを5日間(継続中)パフォーマンスモニタで計測したところ、ハンドル値(イベントハンドル)が少しずつですが積み重なっていました。

この記事の解釈はあっているのでしょうか?そもそもこれは.NETで開発している方々にとっては既知の事実とかなのでしょうか?

どうぞよろしくお願い致します。

[環境]
.NET Framework v1.1(SPなし)
Win2K Pro
VS 2004 Enterprise Edition C#

[使用ツール]
パフォーマンスモニタ
ProcessWalker







ryuuji
ベテラン
会議室デビュー日: 2003/07/10
投稿数: 53
お住まい・勤務地: 東京都
投稿日時: 2004-10-04 12:04
追記します。
どうやら日本語に訳してくれているブログもあるようです。

http://wiki.users.gr.jp/default.aspx/dotNet.cbrumme_ApartAndPumpInCLR
iStation
大ベテラン
会議室デビュー日: 2003/12/08
投稿数: 158
投稿日時: 2004-10-04 12:37
コード:

comObj = null;

GC.Collect();
GC.WaitForPendingFinalizers();
...


これでリーク対策になりませんか?

[ メッセージ編集済み 編集者: iStation 編集日時 2004-10-04 13:07 ]
ryuuji
ベテラン
会議室デビュー日: 2003/07/10
投稿数: 53
お住まい・勤務地: 東京都
投稿日時: 2004-10-04 13:23
iStation様、早速の返信ありがとうございます。

GC.WaitForPendingFinalizers()MSDNで調べました。このコードを追加したテストプログラムも計測してみようかと思います。

ファイナライザが実行されるスレッドの優先順位を上げるメソッドのようですが、これはCOM Interopに関わらずマルチスレッドでアプリケーションを組んだ際のGCの仕組みの問題ということになるでしょうか?
ryuuji
ベテラン
会議室デビュー日: 2003/07/10
投稿数: 53
お住まい・勤務地: 東京都
投稿日時: 2004-10-04 20:33
現在、テストプログラムではCOMオブジェクト(のラッパー)を生成し、使用した後以下のメソッドを明示的に呼び出しているのですが、このReleaseComObject()を使用することが、COMオブジェクト(のラッパー)を使用する作法と考えていたのですが、この認識がそもそも間違っているのでしょうか?

MSDNなど読むと、COMの参照カウンタをデクリメントするなどと書いてありますが、不必要に呼び出すと、オブジェクトが解放されないままリークしてしまうとか。

コード:
private void ReleaseRCW()
{
   if ( _dummyCOM != null ) // _dummyCOMがCOMオブジェクトラッパー
        System.Runtime.InteropServices.Marshal.ReleaseComObject( _dummyCOM );

   _dummyCOM = null; // 明示的にnullを代入し参照をはずす。この時点でGC対象になる
}

1

スキルアップ/キャリアアップ(JOB@IT)