6

I need to use an external assembly that I cannot modify. Suppose that I use a class from that assembly like so:

using (ExternalWidget widget = new ExternalWidget())
{
    widget.DoSomething();
}

Each time I call this code, it leaks unmanaged memory. ExternalWidget implements IDisposable and I have wrapped it in a using statement, but ExternalWidget does not clean up its unmanaged resources.

Since I do not have access to the ExternalWidget code, I cannot fix this issue the right way. Is there any other way that I can free up the memory resources used by ExternalWidget?

4

1 に答える 1

4

それが真のアンマネージメモリ リークであり、コードを変更できない場合は、できることはほとんどありません。フレームワークはそれを検出することも、そのコードをクリーンアップすることもできません。

この場合のアプローチは、そのコンポーネントの分離です。これは、アクセスする際に多くのオーバーヘッドが発生することを意味しますが、他にできることはありません。

アンマネージ コードにはアプリケーション ドメインの概念がないため、別のアプリケーション ドメインでコードを実行することはできません。

それはプロセスレベルを離れます。ExternalWidgetメソッドと共にへの呼び出しを模倣するサービス コントラクトを WCF で作成することをお勧めしShutdownます。

ExternalWidget次に、名前付きパイプ バインディングを介してこのコントラクトを公開する EXE を作成します (セッションを使用するため、各呼び出しがステートレスでない限り、インスタンスを保持できます)。

EXE へのパラメーターとして、一意の識別子 ( を使用Guid) を受け取り、それを WCF サービスのエンドポイントの設定の一部として使用します。

次に、呼び出しを行い、そのインスタンスの処理が完了したら、 ;ExternalWidgetを呼び出します。ShutdownEXE は待機を停止することを認識し、プロセスは終了し、オペレーティング システムはメモリを解放します。

もちろん、ここには膨大なオーバーヘッドがあるため、大量の呼び出しを行っていて、一連の呼び出しごとに新しいプロセスを必要としない場合は、アイデアを呼び出しをカウントするサービスに拡張して、次に、必要に応じてプロセスをリサイクルします (サービスは引き続きシェルアウトする必要があります。そうしないと、リソースが不足します)。

これがマネージメモリの問題であることが判明した場合は、いつでも新しいアプリケーション ドメインを起動し、そこでコードを実行して (必要に応じて結果をマーシャリングして)、アプリケーション ドメインを解放できます。

于 2012-10-25T14:18:52.113 に答える