2

ESRI独自の.NET相互運用機能アセンブリを介してESRIのArcObjectsCOMライブラリを使用する地理データを処理するための.NETアプリケーションに取り組んでいます。

本番環境で実行している場合、プロセスごとのメモリ制限が2GBに達するため、一部の操作中にプロセスがクラッシュする可能性があります。(ArcObjectsは32ビットライブラリです。)これは、一部の処理ステップで多くの一時的なArcObjectsジオメトリオブジェクトが作成される可能性があるためです。FinalReleaseComObjectおよび関連するヘルパーメソッドを使用してこれらのオブジェクトを手動で解放したにもかかわらず、メモリリークが発生し、最終的にメモリが不足します。ただし、をWaitForPendingFinalizers呼び出して定期的に呼び出すことでGC.Collect、 GCにメモリを強制的に解放させFinalReleaseComObject、メモリ使用量を制御することができます。それ以外の場合、プロセスが終了するまで(正常または異常に)多くのオブジェクトがメモリに残ります。

最初の質問:ArcObjects COMオブジェクトによって保持されているメモリがすぐに解放されないのはなぜですか?または、GCが、リリースされたCOMオブジェクトをファイナライズして、クラッシュする前にメモリを再利用するのではなく、プロセスをクラッシュさせるのはなぜですか?

アプリケーションはWindows200864ビットで本番環境で実行されますが、私はWindows732ビットを使用して開発しています。プロセスを本番ボックスでクラッシュさせることはできますが、開発ボックスでクラッシュさせることはできません。これは、ローカルでは通常、デバッグビルドを使用してVisual Studioで実行しているためだと思いましたが、リリースビルドを使用してデバッガーなし(デバッグなしで開始)でも試しましたが、それでもそれほど多くは使用されませんでした本番環境と同じようにメモリを使用し、クラッシュしません。

2番目の質問:なぜですか?

編集:以前の実験では、GC.Collect明示的に呼び出していたとしても、それだけでは不十分であることがわかりました。アルゴリズムを繰り返すたびにメモリ使用量を抑えてから呼び出すユーティリティメソッドがありますGC.CollectGC.WaitForPendingFinalizers

4

1 に答える 1

5

管理対象アプリケーションで使用されるCOMオブジェクトは、COMオブジェクトのインターフェイスを管理対象クライアント(管理対象コンポーネントと非管理対象コンポーネントの間のブリッジ)に複製する管理対象オブジェクトであるランタイム呼び出し可能ラッパー(RCW)の背後にあります。私の記憶が正しければ、実際のCOMインターフェイス参照は、コードではなくRCWによって保持されます。COMオブジェクトを解放すると、実際に解放されるのはRCWですが、それ自体が管理対象オブジェクトであるため、GCがそれをクリーンアップするまで消えることはありません。これが発生すると、RCWが削除され、COMオブジェクトへの最後の参照が失われるため、RCW自体が破棄される可能性があります。(ドキュメントによるとFinalReleaseComObject、参照カウントを0に設定する必要がありますが、過去に同様の動作が見られたため、ドキュメントが正しいかどうか疑問に思います。)

2番目の質問については、推測があります。ストレスの多い環境では、システムに高負荷がかかっていると、GCを実行する機会がないことがわかりました。当時、GCは優先度の低いスレッドで実行されており、アプリケーションはCPUを大量に使用しているため、GCがクリーンアップする機会がなかったと判断しました。時々定期的に呼び出す別のスレッドを追加する必要がGC.Collect()ありました。これにより、GCスレッドが目覚め、魔法をかけるようになりました。あなたは似たようなことに直面しているかもしれません。(これが#1の問題の背後にある理由かもしれません。)

于 2012-10-08T01:21:10.250 に答える