#include <malloc.h> int malloc_info(int options, FILE *stream);
現在の実装では、 options は 0 でなければならない。
インターフェース | 属性 | 値 |
malloc_info() | Thread safety | MT-Safe |
open_memstream(3) 関数を使うと、 malloc_info() の出力を、 ファイルではなくメモリー内のバッファーに直接送ることができる。
malloc_info() 関数は、 malloc_stats(3) と mallinfo(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>
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);