0

悪名高いメモリ リークの問題が時々発生する従来の C++ アプリケーションは、.Net サーバー ベースの Windows アプリケーションから呼び出す必要があります。.Net ガベージ コレクションの時間は決定できず、C++ オブジェクトが破棄されるか、「時間通りに」破棄されない場合があり、予測できない結果が生成され、通常は C# Web アプリがクラッシュします。C++ オブジェクトをできるだけ頻繁にガベージ コレクション スタックにプッシュする最善の方法は何ですか。ただし、COM オブジェクトへの .Net 参照を削除するほど頻繁ではありません。COM オブジェクトはサブオブジェクトを生成できるため、COM オブジェクトの .Net 参照カウントは関数呼び出しだけで変更でき、インスタンス化とは限らないことに注意してください。

メモリ リークが発生し、COM オブジェクトがクリーンアップされないため、IIS が数回トリップしてクラッシュするほどパフォーマンスが低下します。IIS を再起動すると、次回まで問題が修正されます。定期的な再起動は役に立ちますが、忙しい日は営業日中にこれを引き起こす可能性があります.

数年前に.Net 1.1を使用してこれを解決する必要がありました。他の誰かが私の解決策またはより良い解決策を持っているかどうか疑問に思っています。これは ASP.NET ではありません。これは .Net dll です。

最終結果は完全に満足できるものではなく、Web サーバーは数か月ごとにクラッシュしました。

4

2 に答える 2

1

「c++オブジェクトをできるだけ頻繁にガベージコレクションスタックにプッシュするための最良の方法は何ですか」と質問しますが、c++オブジェクトがガベージコレクションされることはありません。多分それをこのように見てください...

一連のc++オブジェクトをインスタンス化するプロセスがあります。これらのc++オブジェクトの一部はCOMオブジェクトを実装しているため、それらの存続期間はAddRef/Releaseを介して管理されます。これらのCOMオブジェクトの一部は.NETワールドにインポートされ、RCW(ランタイム呼び出し可能ラッパー)でラップされます。RCWのみが.NETオブジェクトであり、ガベージコレクションされたヒープに入ります。

あなたの介入がなければ、RCWは最終的にGCされ、それが発生すると、基盤となるCOMオブジェクトに対してリリースが実行されます。GCを待たずにCOMオブジェクトをすぐに解放したい場合は、...を呼び出すことができます。

System.Runtime.InteropServices.Marshal.ReleaseComObject

...またはFinalReleaseComObjectでさえ、それがあなたが望むものであると確信している場合。

質問に戻るには、COMオブジェクトへの.NET参照を解放せずにc++オブジェクトを削除する方法を知りたいと考えています。c ++オブジェクトは.NETヒープに存在しないため、これを直接実現する方法はありません。COMオブジェクトからすべてのc++オブジェクトを削除するメソッドを公開し、それを.NETコードから呼び出すことができます。しかし、COMオブジェクトが、すでに実行しているリークされたすべてのc++オブジェクトを識別できるかどうかを推測します。

うまくいけば、質問で提案したことを達成する方法がない理由を説明しましたが、メモリリークを見つけて修正するのに役立つツールはたくさんあります。LeakDiag(StackOverflowで検索)などのツールを使用して、C++コードがメモリリークしている場所を見つけることをお勧めします。

IIS6以降を使用している場合の実用的な解決策は、アプリケーションプールのリサイクルを構成することです。問題が発生するのに十分なメモリがリークする前にプロセスが強制終了されて再起動されるように数値を微調整できます。通常、ユーザーがダウンタイムに気付かないように機能します。

于 2009-02-26T12:41:35.573 に答える
0

COM +アプリケーションを作成し、使用するCOMクラスをそのアプリケーション内に配置します。このようにして、すべてのCOMオブジェクトが別のプロセスでインスタンス化されます。すべてのCOMオブジェクトを定期的に解放し、COM+アプリケーションプロセスを再起動するだけです。

于 2009-02-26T12:49:16.977 に答える