malloc_info - malloc
の状態をストリームに出力する
#include <malloc.h>
int malloc_info(int options, FILE *stream);
malloc_info() 関数は、
呼び出し元のメモリー割り当て実装の現在の状態を表す
XML 文字列を出力する。
文字列は、
ファイルストリーム
stream に出力される。
出力された文字列には、
全ての割り当て領域の情報が含まれる
(
malloc(3) 参照)。
現在の実装では、
options
は 0
でなければならない。
malloc_info() は、成功すると 0
を返す。
エラーの場合、-1
を返し、
errno
にエラーの原因を示す値を設定する。
- EINVAL
-
options が 0
でなかった。
malloc_info() は glibc バージョン
2.10 で追加された。
この節で使用されている用語の説明については、
attributes(7) を参照。
インターフェース |
属性 |
値 |
malloc_info() |
Thread safety |
MT-Safe |
この関数は GNU
による拡張である。
メモリー割り当て情報は
(C の構造体ではなく) XML
文字列として提供される。
これは、
この情報は時間をたつと
(内部で使用している実装によって)
変わる可能性があるからである。
出力される XML
文字列にはバージョンフィールドが付いている。
open_memstream(3)
関数を使うと、
malloc_info()
の出力を、
ファイルではなくメモリー内のバッファーに直接送ることができる。
malloc_info() 関数は、
malloc_stats(3)
と
mallinfo(3)
の不備を解決するために設定された。
以下のプログラムは最大で
4
つのコマンドライン引数を取り、
最初の 3
つは必須である。
最初の引数は、このプログラムが生成するスレッド数を指定する。
メインスレッドを含む全てのスレッドが第
2
引数で指定した数のメモリーブロックの割り当てを行う。
第 3
引数は割り当てるブロックのサイズを制御する。
メインスレッドはこのサイズのブロックを作成し、
このプログラムが生成する
2
番目のスレッドはこのサイズの
2
倍のサイズのブロックを、
3
番目のスレッドはこのサイズの
3
倍のサイズのブロックを割り当て、
以下同様である。
このプログラムは
malloc_info() を 2
回呼び出し、メモリー割り当て状態を表示する。
最初の呼び出しはスレッドの生成もメモリーの割り当ても行われる前に実行される。
2
回目の呼び出しは全てのスレッドがメモリー割り当てを行った後に実行される。
以下の例では、
コマンドライン引数で、
追加でスレッドを一つ生成し、メインスレッドと追加のスレッドの両方が
10000
個のメモリーブロックを割り当てるように指定している。
メモリーブロックの割り当て後の
malloc_info() では、 2
つの割り当て領域の状態が表示されている。
$ getconf GNU_LIBC_VERSION
glibc 2.13
$ ./a.out 1 10000 100
============ Before allocating blocks ============
<malloc version="1">
<heap nr="0">
<sizes>
</sizes>
<total type="fast" count="0" size="0"/>
<total type="rest" count="0" size="0"/>
<system type="current" size="135168"/>
<system type="max" size="135168"/>
<aspace type="total" size="135168"/>
<aspace type="mprotect" size="135168"/>
</heap>
<total type="fast" count="0" size="0"/>
<total type="rest" count="0" size="0"/>
<system type="current" size="135168"/>
<system type="max" size="135168"/>
<aspace type="total" size="135168"/>
<aspace type="mprotect" size="135168"/>
</malloc>
============ After allocating blocks ============
<malloc version="1">
<heap nr="0">
<sizes>
</sizes>
<total type="fast" count="0" size="0"/>
<total type="rest" count="0" size="0"/>
<system type="current" size="1081344"/>
<system type="max" size="1081344"/>
<aspace type="total" size="1081344"/>
<aspace type="mprotect" size="1081344"/>
</heap>
<heap nr="1">
<sizes>
</sizes>
<total type="fast" count="0" size="0"/>
<total type="rest" count="0" size="0"/>
<system type="current" size="1032192"/>
<system type="max" size="1032192"/>
<aspace type="total" size="1032192"/>
<aspace type="mprotect" size="1032192"/>
</heap>
<total type="fast" count="0" size="0"/>
<total type="rest" count="0" size="0"/>
<system type="current" size="2113536"/>
<system type="max" size="2113536"/>
<aspace type="total" size="2113536"/>
<aspace type="mprotect" size="2113536"/>
</malloc>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <malloc.h>
#include <errno.h>
static size_t blockSize;
static int numThreads, numBlocks;
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
static void *
thread_func(void *arg)
{
int tn = (int) arg;
/* The multiplier '(2 + tn)' ensures that each thread (including
the main thread) allocates a different amount of memory */
for (int j = 0; j < numBlocks; j++)
if (malloc(blockSize * (2 + tn)) == NULL)
errExit("malloc-thread");
sleep(100); /* Sleep until main thread terminates */
return NULL;
}
int
main(int argc, char *argv[])
{
int sleepTime;
if (argc < 4) {
fprintf(stderr,
"%s num-threads num-blocks block-size [sleep-time]\n",
argv[0]);
exit(EXIT_FAILURE);
}
numThreads = atoi(argv[1]);
numBlocks = atoi(argv[2]);
blockSize = atoi(argv[3]);
sleepTime = (argc > 4) ? atoi(argv[4]) : 0;
pthread_t *thr = calloc(numThreads, sizeof(*thr));
if (thr == NULL)
errExit("calloc");
printf("============ Before allocating blocks ============\n");
malloc_info(0, stdout);
/* Create threads that allocate different amounts of memory */
for (int tn = 0; tn < numThreads; tn++) {
errno = pthread_create(&thr[tn], NULL, thread_func,
(void *) tn);
if (errno != 0)
errExit("pthread_create");
/* If we add a sleep interval after the start-up of each
thread, the threads likely won't contend for malloc
mutexes, and therefore additional arenas won't be
allocated (see malloc(3)). */
if (sleepTime > 0)
sleep(sleepTime);
}
/* The main thread also allocates some memory */
for (int j = 0; j < numBlocks; j++)
if (malloc(blockSize) == NULL)
errExit("malloc");
sleep(2); /* Give all threads a chance to
complete allocations */
printf("\n============ After allocating blocks ============\n");
malloc_info(0, stdout);
exit(EXIT_SUCCESS);
}
mallinfo(3),
malloc(3),
malloc_stats(3),
mallopt(3),
open_memstream(3)
この man ページは Linux
man-pages
プロジェクトのリリース
5.10
の一部である。プロジェクトの説明とバグ報告に関する情報は
https://www.kernel.org/doc/man-pages/
に書かれている。