GNU/Linux >> Linux の 問題 >  >> Linux

ヒープ上のプロセスによって割り当てられたバイト数をプログラムで検出する方法は?

mallinfo() が必要だと思います:

#include <malloc.h>


struct mallinfo *info;

info = mallinfo();

printf ("total allocated space:  %llu bytes\n", info->uordblks);
printf ("total free space:       %llu bytes\n", info->fordblks);

struct mallinfo 構造は技術的なもので、malloc() 実装に固有のものです。でも欲しい情報はそこにある。値を報告する方法は次のとおりです。

mallinfo.arena = "Total Size (bytes)" 
mallinfo.uordblks = "Busy size (bytes)" 
mallinfo.fordblks = "Free size (bytes)" 
mallinfo.ordblks = "Free blocks (count)" 
mallinfo.keepcost = "Top block size (bytes)" 
mallinfo.hblks = "Blocks mapped via mmap() (count)" 
mallinfo.hblkhd = "Bytes mapped via mmap() (bytes)"

これら 2 つは使用されていないと言われていますが、私のシステムでは変更されているようで、有効である可能性があります:

mallinfo.smblks = "Fast bin blocks (count)"
mallinfo.fsmblks = "Fast bin bytes (bytes)"

もう 1 つの興味深い値は、"sbrk (0)" によって返されます


多くの可能性があります。

どのくらい正確である必要がありますか? cat /proc/${PID}/status | 経由で有用なデータを取得できます。 grep VmData .

#定義できます 独自の ma​​lloc() , realloc() , calloc() 、および free() 独自のカウンターの背後にある実際の関数をラップします。ここでは、__FILE__、__LINE__、および __func__ を使用して、簡単なテストでコア リークを簡単に特定できるようにすることができます。 しかし、それはあなた自身のコードを計測するだけです!

(同様に、デフォルトの operator new を再定義することもできます および 演算子の削除 メソッド、配列バリアントと非配列バリアントの両方、および std::bad_alloc バリアントと std::nothrow_t バリアントの両方をスローします。 繰り返しますが、これは自分のコードのみを計測します!)

(注意:ほとんどの C++ システムでは、new 最終的に malloc() を呼び出します .その必要はありません。特にインプレース new !ただし、通常は新しい malloc() を利用する . (または、以前にmalloc()されたメモリ領域で動作します .) そうしないと、複数のヒープ マネージャーを使用して本当にファンキーなものになってしまいます...)

sbrk(0) を使用できます データ セグメントが現在設定されている場所を確認します。それはそれほど素晴らしいことではありません。これは非常に粗い測定値であり、ヒープ内の穴 (未使用のメモリ領域) は考慮されていません。 (VmData を使用した方がはるかに優れています) /proc/${PID}/status の行 .) しかし、一般的なアイデアを探しているだけなら...

malloc()/free()/etc をトラップできます 独自の共有ライブラリを作成し、LD_PRELOAD を介して実際のバージョンの代わりにそれを使用するようプロセスに強制する . dlopen()/dlsym() を使用できます *real* malloc()/free()/etc をロードして呼び出す .これは非常に美しく機能します。元のコードは変更されておらず、再コンパイルさえされていません。ただし、このライブラリをコーディングするときは再入可能な状況に注意してください。また、プロセスが最初に malloc()/calloc()/realloc() を呼び出すことに注意してください。 dlopen()/dlsym() の前 実際の関数のロードを完了することができます。

Valgrind などのツールをチェックしてみてください。

もう一度、おそらく mtrace() あなたが欲しいものですか?または __malloc_hook ?非常にプロプライエタリ (GNU) &非標準... しかし、あなたは "Linux" とタグ付けされています...


自動で簡単なことはありません それがあなたが求めているものなら、それを行う方法。基本的に、カウンター変数を使用して手動でヒープ割り当てを追跡する必要があります。問題は、プログラムのどの部分がヒープにメモリを割り当てているかを制御するのが難しいことです。特に、制御できないほど多くのライブラリを使用している場合はそうです。さらに複雑なことに、プログラムがヒープ メモリを割り当てる方法は 2 つあります:new または malloc . (sbrk のような直接の OS 呼び出しは言うまでもありません .)

グローバル演算子 new をオーバーライドできます 、および new への呼び出しごとにグローバル集計を増やします。ただし、これには、プログラムが malloc を呼び出す時間が含まれているとは限りません。 、またはプログラムがクラス固有の new を使用する場合 オーバーライド。 malloc をオーバーライドすることもできます マクロを使用しますが、これは必ずしも移植可能ではありません。また、 malloc のすべてのバリエーションをオーバーライドする必要があります 、 realloc のように 、 calloc など。これはすべて、一部の実装では new という事実によってさらに複雑になります。 それ自体が malloc を呼び出す可能性があります .

したがって、基本的に、プログラム内からこれを適切に行うことは非常に困難です。代わりにメモリ プロファイラ ツールを使用することをお勧めします。


Linux
  1. バッシュを検出する方法>=4.0?

  2. LinuxでIPアドレスの変更をプログラムで検出する方法は?

  3. バックグラウンドプロセスのプロセスIDを取得するには?

  1. 具体的には、fork() は Linux で malloc() から動的に割り当てられたメモリをどのように処理しますか?

  2. Linux でプロセスのヒープ サイズを確認する方法

  3. 決定論的 malloc の実装方法

  1. ゾンビプロセスを強制終了する方法

  2. プロセスへのポートを識別する方法は?

  3. プロセスの環境変数を読み取る方法