C++プログラムでメモリ割り当てを追跡する方法を探しています。私はnotメモリリークに興味がありますが、これはほとんどのツールが見つけようとしているもののようですが、アプリケーションのメモリ使用量プロファイルを作成しています。理想的な出力は、関数名の大きなリストに加えて、時間の経過とともに割り当てられた最大バイト数のいずれか、またはより適切な、時間の経過に伴うヒープのグラフィカルな表現です。横軸は時間、縦軸はヒープスペースです。すべての関数は独自の色を取得し、割り当てられたヒープバイトに従って線を描画します。同様に、割り当てられたオブジェクトタイプを識別するためのボーナスポイント。
アイデアは、メモリのボトルネックを見つけること/どの関数/スレッドが最もメモリを消費するかを視覚化することであり、さらなる最適化の対象とすべきです。
Purify、BoundsChecker、およびAQTimeについて簡単に説明しましたが、それらは私が望んでいるものではないようです。 Valgrindは適切に見えますが、私はWindowsを使用しています。 Memtrack は有望に見えますが、ソースコードを大幅に変更する必要があります。
私のグーグルスキルは私を失敗させたに違いありません、それはそれほど珍しいリクエストではないように思われますか?そのようなツールを作成するために必要なすべての情報は、プログラムのデバッグシンボルとランタイムAPI呼び出しからすぐに利用できるはずです-いいえ。
ゲーム開発のためのPCのメモリ使用量の監視 には、私が探していたもののほぼ完璧な例が含まれています。実行に時間がかかりましたが、記事の著者は非常に役に立ちました。ツールのソースコードは、ここで Memtracer にあります。
また、 [〜#〜] sweng [〜#〜] (ソフトウェアエンジニアリングメーリングリスト)で多くの有益な回答を得ました。スレッドは「[Sweng-Gamedev] C++メモリ使用量を監視しますか?」と呼ばれます。
ValgrindとそのツールMassifを使用します。その出力例(その一部):
99.48% (20,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->49.74% (10,000B) 0x804841A: main (example.c:20)
|
->39.79% (8,000B) 0x80483C2: g (example.c:5)
| ->19.90% (4,000B) 0x80483E2: f (example.c:11)
| | ->19.90% (4,000B) 0x8048431: main (example.c:23)
| |
| ->19.90% (4,000B) 0x8048436: main (example.c:25)
|
->09.95% (2,000B) 0x80483DA: f (example.c:10)
->09.95% (2,000B) 0x8048431: main (example.c:23)
したがって、詳細な情報を取得できます。
ヒープ割り当てとスタック割り当てを追跡できます(デフォルトではオフになっています)。
PS。 Windowsを使用していると読みました。ただし、可能性のあるツールから得られるものの写真を提供するため、答えは残しておきます。
マイクロソフトは、メモリトラッキング機能を十分に文書化しています。ただし、何らかの理由で、それらは開発者コミュニティではあまり知られていません。これらはCRTデバッグ関数です。適切な出発点は CRT Debug Heap functions です。
詳細については、次のリンクを確認してください
汎用のC++メモリトラッカーの場合、以下をオーバーロードする必要があります。
global operator new
global operator new []
global operator delete
global operator delete []
any class allocators
any in-place allocators
トリッキーなビットは有用な情報を取得しています。オーバーロードされた演算子はアロケーターのサイズ情報と削除用のメモリポインターのみを持っています。 1つの答えは、マクロを使用することです。知っている。不快な。例-すべてのソースファイルからインクルードされるヘッダーに配置します。
#undef new
void *operator new (size_t size, char *file, int line, char *function);
// other operators
#define new new (__FILE__, __LINE__, __FUNCTION__)
そしてソースファイルを作成します:
void *operator new (size_t size, char *file, int line, char *function)
{
// add tracking code here...
return malloc (size);
}
上記は、クラススコープでnew演算子が定義されていない場合にのみ機能します。クラススコープにある場合は、以下を実行します。
#define NEW new (__FILE__, __LINE__, __FUNCTION__)
「新しいタイプ」を「新しいタイプ」に置き換えますが、これには多くのコードを潜在的に変更する必要があります。
マクロなので、メモリトラッカーの削除は非常に簡単で、ヘッダーは次のようになります。
#if defined ENABLED_MEMORY_TRACKER
#undef new
void *operator new (size_t size, char *file, int line, char *function);
// other operators
#define NEW new (__FILE__, __LINE__, __FUNCTION__)
#else
#define NEW new
#endif
実装ファイル:
#if defined ENABLED_MEMORY_TRACKER
void *operator new (size_t size, char *file, int line, char *function)
{
// add tracking code here...
return malloc (size);
}
endif
これも試してください: Memory Validator
Mac OS Xでは、コードプロファイリングツールSharkを使用してこれを行うことができます、IIRC。
「経時的なヒープのグラフィカルな表現」-探しているものに近いものが Intel(R)Single Event API に実装されており、詳細は この記事 にあります。 (ここに置くのはかなり大きい)。
ブロックサイズごとの割り当てのタイムラインを表示し、コード全体にマークを追加して、全体像をよりよく理解できます。
Xcodeでは、Instrumentsを使用して、割り当て、VM使用状況、およびその他のいくつかのパラメーターを追跡できます。iOS開発者の間で最も人気がありますが、試してみる価値があります。
Visual Studio IDEは、組み込みのヒーププロファイリングサポート(2015年以降)を備えています。これは、おそらく最も簡単に開始できます。 /方法。
CRTにはデバッグとプロファイルのサポートもあり、これはより詳細でより低レベルです。他のツールを使用して、データを追跡し、結果をプロットできます。
特に、_CrtMemCheckpoint
および関連する関数。