10

混合モードの C++/CLR .NET アプリケーションでメモリ リークが遅いという問題があります。

(「/clr」コンパイラ設定で VS2008 C++/CLR Windows フォーム アプリにリンクされた C++ ネイティブ スタティック ライブラリです)

典型的な動作: アプリは 30 MB (プライベート メモリ) を使用して起動します。次に、シミュレートされた高負荷の下で実行すると、1時間ごとにメモリリークが遅くなります。これにより、アプリが数日または数週間ライブになるようにシミュレートされます。

Visual Studio CRT ライブラリに付属する CRT デバッグ機能を含むいくつかのツールを使用して、メモリ リークを追跡しようとしました。また、市販のリーク検出ツール (「Memory Validator」) も使用しました。

両方とも、シャットダウン時のメモリ リークはごくわずかであると報告されています (数 KB に達する小さなエントリがいくつかありますが、私は気にしていません)。また、実行時に追跡されたメモリがそれほど大きくないように見えることがわかります(したがって、保持されていてアプリの終了時にのみ解放されるメモリだけではないと思います)。リストされたメモリは約 5 MB です (合計 > 30 MB のうち)。

ツール (Memory Validator) は、すべてのメモリ使用量 (malloc、new、仮想メモリ割り当て、およびその他の種類のメモリ割り当て全体を含む) を追跡するように設定されています。基本的に、追跡するメモリのすべての設定が選択されています。

.NET イメージは、(perfmon から) 約 1.5 MB のメモリを使用していると報告しています。

最後に、ネイティブ コンソール アプリケーションとして実行されるバージョンのアプリがあります (完全にネイティブ - CLR ではありません)。これは、UI 要素がないことを除いて、混合モードと 95% 同じです。これはまったくメモリ リークしていないようで、約 5MB のプライベート バイトでピークに達します。

つまり、基本的にここで理解しようとしているのは、どのネイティブ コードもメモリ リークしているとは思わないということです。

パズルのもう1つのピース:2.0フレームワーク(私がそうです)をターゲットにした場合の混合モードアプリケーションでのメモリリークに言及するこれを見つけました:http://support.microsoft.com/kb/961870

残念ながら、詳細は腹立たしいほどまばらなので、関連性があるかどうかはわかりません. 私は 2.0 ではなく 3.5 フレームワークをターゲットにしようとしましたが、それでも同じ問題がありました (これを正しく実行しなかった可能性があります)。

誰にも提案はありますか?

私を助けるかもしれないいくつかのこと:

  • 私が追跡していない他の種類のメモリ割り当てはありますか?
  • 数字が合わないのはどうして?5 MB の CRT メモリ使用量と 1.5 MB の .NET メモリが使用されるのに、アプリ全体で 30 MB のプライベート バイトを使用するのはなぜですか? それはすべて .NET フレームワークに縛られているのでしょうか? これらがリーク ツールに表示されないのはなぜですか? .NET フレームワークは、ある種の割り当てられたメモリとして表示されませんか?
  • 混合モードのアプリでうまく機能する他のリーク検出ツールはありますか?

助けてくれてありがとう

ジョン

4

5 に答える 5

7

OK私はついに問題を見つけました。

/ EH(例外処理)の設定が正しくないことが原因です。

基本的に、混合モードの.NETアプリでは、静的にリンクされたすべてのライブラリがデフォルトの/EHではなく/EHaでコンパイルされていることを確認する必要があります。

(アプリ自体も/ EHaでコンパイルする必要がありますが、これは当然のことです。使用しない場合、コンパイラーはエラーを報告します。問題は、他の静的ネイティブライブラリにリンクする場合です。)

問題は、/ EHでコンパイルされたネイティブライブラリ内でスローされたアプリのマネージドビットでキャッチされた例外が、例外を正しく処理しなくなることです。C++オブジェクトのデストラクタは正しく呼び出されません。

私の場合、これはまれな場所でのみ発生したため、発見するのに何年もかかりました。

于 2010-01-10T11:40:51.303 に答える
0

参照リークがある可能性があります。ANTS プロファイリング ソフトウェアを調べてください。アリプロファイラー

参照リークは、メモリ リークに相当する .net です。ガベージ コレクションを停止するオブジェクトへの参照を保持すると、使用中のメモリが増加し始めます。

于 2009-07-09T08:27:23.393 に答える
0

GDI+ や他の多くの API を使用している場合に発生する可能性があります。

静的分析ツール FXCop を実行すると、インターフェイスを提供するオブジェクトで dispose を呼び出した (または "using" ステートメントを使用した) かどうかをチェックするルールがあります。.Net では、関数がアンマネージ コードを使用する場合、リソース/メモリをリークしないように、通常は dispose または close メソッドを提供します。

于 2009-07-09T10:26:58.363 に答える
0

試してみてください: DebugDiags
いくつかのメモリ ダンプを生成すると、どのメモリが割り当てられたかの要約が表示されます。また、PDB の検索に応じて、それが誰によって割り当てられたかがわかります。

于 2009-07-09T07:54:09.123 に答える