#include <malloc.h> int malloc_info(int options, FILE *stream);
As currently implemented, options must be zero.
The open_memstream(3) function can be used to send the output of malloc_info() directly into a buffer in memory, rather than to a file.
The malloc_info() function is designed to address deficiencies in malloc_stats(3) and mallinfo(3) .
The program calls malloc_info() twice to display the memory-allocation state. The first call takes place before any threads are created or memory allocated. The second call is performed after all threads have allocated memory.
In the following example, the command-line
arguments specify the creation of one additional thread, and both the main
thread and the additional thread allocate 10000 blocks of memory. After
the blocks of memory have been allocated, malloc_info() shows the state
of two allocation arenas.
$ getconf GNU_LIBC_VERSIONglibc 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 j; int tn = (int) arg; /* The multiplier aq(2 + tn)aq ensures that each thread (including the main thread) allocates a different amount of memory */ for (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 j, tn, sleepTime; pthread_t *thr; 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; thr = calloc(numThreads, sizeof(pthread_t)); if (thr == NULL) errExit("calloc"); printf("============ Before allocating blocks ============\n"); malloc_info(0, stdout); /* Create threads that allocate different amounts of memory */ for (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 wonaqt contend for malloc mutexes, and therefore additional arenas wonaqt be allocated (see malloc(3)). */ if (sleepTime > 0) sleep(sleepTime); } /* The main thread also allocates some memory */ for (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); }