ワーカースレッドでCOMオブジェクトを使用するマルチスレッドアンマネージドアプリケーションを作成しました。 COMとしてエクスポートされた.NETオブジェクトを使用して作業を開始するまでは、すべてうまく行きました。COM&C#を使用したマルチスレッドアプリケーションでメモリリークが発生する
.NETオブジェクトの機能の一部をコメントとして取り上げ、.NETオブジェクト内からCOMオブジェクトを使用する方法まで説明しました。要約すると:
- 私のプログラムは、いくつかのワーカースレッドを開始します。
- 各ワーカースレッドは、作業を行うために.NETベースのCOMオブジェクトを初期化します。
- .NETベースのCOMオブジェクトは、アンマネージCOMオブジェクトを内部的に使用します。
驚いたことに、OutOfMemory例外が表示されるまで、アプリケーションのメモリ消費が着実に上昇し始めました。私はこの機能をコメントアウトした場合
void DoSomeWork()
{
IComObject O = new ComObjectClass();
try
{
// do something
}
finally
{
Marshal.ReleaseComObject(O);
}
}
、メモリリークが消える:
は、ここに私の.NET実装です。 GC.Collect()を呼び出すと、メモリリークが発生します。
何が起こっているのでしょうか?
EDIT:コメントや回答に基づいていくつかの詳細情報:
- 作成されたすべてのスレッドがMTAで実行されています。
- すべてのCOMオブジェクトはIMarshalを実装し、フリースレッドマーシャラを使用します。
- 何が何であるかは関係ありません。int i = 0; i ++;漏れを生成する。
- ComObjetClassが指摘するオブジェクトは古いものであり、テストされています。これは、それが欠陥ではないことを意味するものではありませんが、眩しいものではありません。
- 私は、メインスレッドと別の作成されたスレッドの両方でC#プログラムからCOMオブジェクトを繰り返し作成しようとしました。どちらの場合も、メモリリークは消えました。管理されていないコードから管理されたコードへのクロスとバックは不可欠です。それを削除すると、問題が消えてしまいます。
何が//何かにありますか?場合によっては、アンマネージコードで作成された新しいオブジェクトがあります。 – Grzenio
"do smth"では、2つのCOMオブジェクトを一緒に接続すると、メモリリークが発生する危険性があります。コードは何が起こっているのかを理解するのに役立ちます。 – sharptooth
問題が実際にCOMオブジェクトクラスにある場合はどうでしょうか?それは間違った参照カウントメカニズムを持っているのですか?それを他のCOMオブジェクトに置き換えるとどうなりますか? – sharptooth