FASTMM4またはデフォルトのメモリマネージャを使用して、すべてのアプリケーションでインスタンス化されたすべてのオブジェクトを一覧表示するにはどうすればよいですか?
5 に答える
FastMM4でこれを行うこともできますが、複雑になります。ScanForMemoryLeaksプロシージャのコードを調べて、どのように実行されるかを確認してください。
このルーチンは、割り当てられたすべてのヒープメモリを予想されるメモリリークのリストと照合し、カウントやオブジェクトが見つかった場合のオブジェクトクラス名など、表示されるすべてのものを報告します。割り当てられたすべてのヒープメモリをチェックし、見つかったすべてのオブジェクトのカウントとオブジェクトクラス名を報告するので、これは非常によく似たタスクです。登録されたポインタリストのチェックを省略し、オブジェクトではないものをすべて除外します。
サポートされておらず、推奨されていませんが、状況によっては、TObjectを編集して、作成と破棄を記録できる場合があります。すべてのオブジェクトがTObjectであるため、これでうまくいく場合があります。ただし、VCLの変更は非常に嫌われているので、同じことを行うためにHelperオブジェクト(2006年から利用可能だと思います)を使用できるでしょうか。作成した各オブジェクトの詳細を別のリストなどに書き込みます。
Tony Allenの提案を実装する興味深い方法は、実行時にオブジェクトの作成メソッドと破棄メソッドをフックすることかもしれません。Google Codeには、AsmProfilerプロジェクトの一部である興味深いライブラリがあります(私見では非常にすばらしい作業です)。これは、すべての重労働を行うKOLDetoursユニットへのリンクです。
FWIW Delphi 4/5日に、オブジェクトの作成/破棄をオプションで追跡するインストルメント化された基本クラスを含むフレームワークを実装しました。これは、オブジェクトのリークなどを追跡するのにうまく機能しましたが、膨大な量の情報を生成しました。シャットダウン時にどのオブジェクトがリークしたかを知る必要がある場合は、FASTMM4の方がはるかに優れたオプションです。
SetMemoryManagerを呼び出すことにより、メモリマネージャーを変更できます。単純なスタブとなる独自のMMを作成できます。これにより、すべての呼び出しが古いMM(FastMM、GetMemoryManagerを呼び出すことで取得できます)にリダイレクトされ、すべてのメモリ操作がどこかに記録されます。呼び出しスタックを調べることで、オブジェクトの作成/破棄を検出できます。呼び出しは、TObjectのNewInstanceメソッドから行う必要があります。
これは、完全に試されたわけではなく、役立つはずのアイデアですが、それはあなたを遠ざけるでしょう:
次の方法でクラスヘルパーを作成します。
コンストラクターを使用してジェネリックTobjectクラスヘルパーを記述します。
コンストラクターをオーバーライドするクラスのカスタム/特定のクラスヘルパーを記述します。
freeメソッドを使用して汎用Tobjectクラスヘルパーを記述します。
freeメソッドをオーバーライドするクラスのカスタム/特定のクラスヘルパーを作成します。
最後に、すべてのコードが.Destroyから.Freeに変更されていない場合は、.Freeを呼び出しているかどうかを確認します。すべてのオブジェクトをリストから削除する場合。
リストしたい各ユニットのクラスヘルパーと一緒にユニットを含めます。
また、そのユニットにグローバルリストを作成します。
コンストラクターで単に書く
継承された作成;
GlobalObjectList.Add(Self);
無料のメソッドで次のように記述します。
GlobalObjectList.Remove(Self);
継承された無料;
これはスレッドセーフではない可能性があり、ジェネリックまたはジェネリックメソッドを使用した初期化では失敗する可能性があります。ジェネリックはまだあちこちでバグがあるように見えるため、マイレージはクリティカルセクションやスレッドに関連している可能性があります。