6

Delphi 7 を使用して大規模なアプリケーションでメモリ使用量をデバッグしようとしています。fastmm デバッグ フル dll をインストールして、リークの問題を解決することができました。

また、メモリ使用トラッカーもインストールして、割り当てられたブロックとそのサイズを確認できるようにしました。

私の質問は、ブロックが割り当てられた場所を見つける方法はありますか? メモリが解放されなかった場合、スタック トレースが出力されるため、それが可能であることはわかっています。特定の割り当てのスタック トレースを出力するために fastmm を「突く」方法はありますか?

副次的な質問: 割り当ての開始アドレスがわかっている場合、オブジェクトがどのクラスであるかを調べる方法はありますか? (割り当てがオブジェクトに対するものであると仮定します。

4

3 に答える 3

5

次のいずれかを実行できます。

  • LogAllocatedBlocksToFile手順を使用してみてください。そのパラメーターが 0ALastAllocationGroupToLogより小さいAFirstAllocationGroupToLogかゼロの場合、すべてのブロックとその割り当て呼び出しスタックがログに記録されます。ただし、アプリに多くのメモリが割り当てられている場合は、長時間待機する準備をしてください。約 4 時間の待機時間と 1.5Gb の結果ファイルを経験しました。(補足:このような大きなファイルを表示するにはgloggを使用してください)
  • FastMM4.pas実装がインターフェイスに表示されるように変更LogCallStackします。または、から直接使用することもできますFastMM_FullDebugMode.dll

副次的な質問:DetectClassInstance関数を使用してみてください。

于 2013-01-19T03:24:54.880 に答える
2

コメントで、アプリの終了時にアプリのメモリがきれいにクリーンアップされると言ったことを考えると、論理的なメモリ リークを探しているように聞こえます。それらをきれいにするコードが存在するため、それらはきれいになります。

例:

  • アプリケーションを所有者として使用して TForm を作成し、それを参照する変数は、フォームのユニットを作成するときに Delphi が作成するグローバル変数です。
  • フォームの CloseAction を caHide に構成します (OnClose イベント内)。
  • フォームを表示して操作する
  • フォームを閉じて、アプリが閉じるまで使用しないでください
  • アプリを閉じます。これにより、アプリケーションは所有するすべてのオブジェクトをクリアします

したがって、FastMM が簡単に検出できる種類の物理メモリ リークではなく、論理メモリ リークがあります。アプリケーションが終了するまで仮想の TForm を有効にするつもりはなかったので、意味的にリークしましたが、参照されており、アプリケーションの最後にそれを破棄するコードがあるため、FastMM への割り当ては正常です。

つまり、メモリ マネージャーのメモリ ダンプではなく、メモリ プロファイラーが必要なようです。

于 2013-01-18T19:09:23.533 に答える
2

FullDebugMode を使用し、データをファイルに書き込む条件を有効にすると、まさに求めているものが得られるはずです。プログラムがシャットダウンすると、リークした割り当てごとにスタック トレースが書き込まれます。(メモリ リークが多いプログラムをデバッグしている場合、これには時間がかかることがあります。リークしている項目が他のオブジェクトを多数保持するコンテナーである場合、シャットダウンが 10 分以上続くようです。)

于 2013-01-18T01:09:28.110 に答える