4

パフォーマンスの高いランタイム メモリ メトリックが必要なので、new&のオーバーロードに基づいてメモリ トラッカーを作成しましたdelete。基本的に、ヒープ内の割り当てをウォークし、断片化、サイズ、時間、数、コールスタックなど、それらに関するすべてを分析できます。ただし、2 つの致命的な欠陥があります。他の DLL で割り当てられたメモリを追跡できず、オブジェクトの所有権DLL に渡されるか、逆にクラッシュが発生します。そして、いくつかの小さな欠陥: ユーザーが追跡されていないmalloc代わりに使用する場合new。または、ユーザーがクラスを定義した場合new/ delete

これらの欠陥を取り除くにはどうすればよいですか? new/をオーバーロードすることで、これを根本的に間違って進めているに違いないと思いますdeleteが、もっと良い方法はありますか?

4

3 に答える 3

4

これを実装する正しい方法は、回り道と、独自のプロセスで実行される別のツールを使用することです。手順はおおよそ次のとおりです。

  1. リモート プロセスでメモリ割り当てを作成します。
  2. dll をロードする小さなローダーのコードを配置します。
  3. CreateRemoteThreadローダーを実行する API を呼び出します。
  4. ロードされた dll の内部から、alloc/dealloc 関数の回り道 (フック、インターセプター) を確立します。
  5. 通話を処理し、アクティビティを追跡します。

この方法でツールを実装する場合、どの DLL から、または直接 exe からメモリ割り当てルーチンが呼び出されるかは重要ではありません。さらに、必ずしも自分でコンパイルしたものではなく、任意のプロセスからのアクティビティを追跡できます。

MS Windows では、リモート プロセスの仮想アドレス空間の内容を確認できます。この方法で収集された仮想アドレス空間の使用状況を、次のようにヒストグラムで要約できます。

ここに画像の説明を入力

この図から、ターゲット プロセスにどのサイズの仮想割り当てがいくつ存在するかを確認できます。

ここに画像の説明を入力

上の図は、32 ビット MSVC DevEnv での仮想アドレス空間の使用状況の概要を示しています。ブルーのストライプはエモリーのコミットされた部分を意味し、マゼンタのストライプは予約済みです。緑色は、アドレス空間の占有されていない部分です。

下位アドレスはかなり断片化されているのに対し、中間領域は断片化されていないことがわかります。上位アドレスの青い線 - プロセスにロードされるさまざまな dll。

于 2012-07-06T00:21:59.697 に答える
0

new/deleteおよびmalloc/によって呼び出される一般的なメモリ管理ルーチンを見つけて、freeそれらをインターセプトする必要があります。通常は最後にmalloc/freeですが、念のために確認してください。

UNIX では、LD_PRELOADこれらのルーチンを再実装したライブラリを使用します。Windowsでは、少しハックする必要がありますが、このリンクはプロセスの適切な説明を提供しているようです. 基本的には、Microsoft Research の Detoursを使用することをお勧めします。

于 2012-07-06T00:21:37.467 に答える
0

モジュール間でオブジェクトの所有権を渡すことには根本的な欠陥があります。カスタムアロケータで表示されましたが、他にも失敗するケースがたくさんあります:

  • コンパイラのアップグレード、一部の DLL のみの再コンパイル
  • 異なるベンダーのコンパイラの混在
  • ランタイム ライブラリの静的リンク

ほんの数例を挙げると。オブジェクトを割り当てた同じモジュールからすべてのオブジェクトを解放します (多くの場合、 などの削除関数をエクスポートしますIUnknown::Release())。

于 2012-07-06T00:22:06.177 に答える