MALLOC_INFO(3) | Руководство программиста Linux | MALLOC_INFO(3) |
ИМЯ¶
malloc_info - экспортирует состояние malloc в поток
СИНТАКСИС¶
#include <malloc.h>
int malloc_info(int options, FILE *stream);
ОПИСАНИЕ¶
Функция malloc_info() экспортирует строку XML, описывающую текущее состояние реализации выделения памяти вызывающего. Строка печатается в файловый поток stream. В экспортируемой строке содержится информация о всех областях (arenas) (смотрите malloc(3)).
В текущей реализации значение options должно быть равно нулю.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ¶
При успешном выполнении malloc_info() возвращается 0; при ошибке возвращается -1, а в errno помещается код ошибки.
ОШИБКИ¶
- EINVAL
- Значение options не равно.
ВЕРСИИ¶
Функция malloc_info() впервые появилась в glibc 2.10.
АТРИБУТЫ¶
Описание терминов данного раздела смотрите в attributes(7).
Интерфейс | Атрибут | Значение |
malloc_info() | Безвредность в нитях | MT-Safe |
СООТВЕТСТВИЕ СТАНДАРТАМ¶
Эта функция является расширением GNU.
ЗАМЕЧАНИЯ¶
Информация о выделении памяти предоставляется в виде строки XML (а не в структуре C), так как структура со временем может меняться (при изменении в реализации). Возвращаемая строка XML содержит поле версии.
Для отправки вывода malloc_info() в буфер памяти, а не в файл можно использовать функцию open_memstream(3).
Функция malloc_info() разработана для компенсации нехватки данных из malloc_stats(3) и mallinfo(3).
ПРИМЕР¶
Программа, представленная ниже, принимает до четырёх параметров командной строки, три из которых обязательны. В первом параметре задаётся количество нитей, которые должна создать программа. Все нити, включая главную нить, выделяют количество блоков памяти, заданное в втором параметре. В третьем параметре задаётся размер выделяемых блоков. Главная нить создает блоки этого размера, вторая нить создаваемая программой, выделяет блоки двукратного размера, третья нить выделяет блоки трёхкратного размера и так далее.
Чтобы показать состояние выделения памяти программа дважды вызывает malloc_info(). Первый раз вызов делается до создания нитей и выделения памяти. Второй вызов выполняется после того, как все нити выделят память.
В следующем примере аргументами командной строки задаётся создание одной дополнительной нити и что главная и дополнительная нить выделяют 10000 блоков памяти. После того, как блоки памяти выделены, malloc_info() показывает состояние двух областей выделения.
$ getconf GNU_LIBC_VERSION glibc 2.13 $ ./a.out 1 10000 100 ============ до выделения блоков ============ <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> ============ после выделения блоков ============ <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;
/* Множитель '(2 + tn)' для обеспечения того, что каждая
нить (включая главную) выделяет разное количество памяти */
for (j = 0; j < numBlocks; j++)
if (malloc(blockSize * (2 + tn)) == NULL)
errExit("malloc-thread");
sleep(100); /* Спим, пока главная нить не завершит работу */
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("============ до выделения блоков ============\n");
malloc_info(0, stdout);
/* Создаём нити, которые выделяют разное количество памяти */
for (tn = 0; tn < numThreads; tn++) {
errno = pthread_create(&thr[tn], NULL, thread_func,
(void *) tn);
if (errno != 0)
errExit("pthread_create");
/* если мы добавим задержку после запуска каждой нити,
то нити, вероятно, не будут бороться за мьютекс malloc,
и поэтому дополнительные области выделены
не будут (смотрите malloc(3)) */
if (sleepTime > 0)
sleep(sleepTime);
}
/* главная нить также выделяет память */
for (j = 0; j < numBlocks; j++)
if (malloc(blockSize) == NULL)
errExit("malloc");
sleep(2); /* ждём, чтобы потоки успели
выделить память */
printf("\n============ после выделения блоков ============\n");
malloc_info(0, stdout);
exit(EXIT_SUCCESS); }
СМ. ТАКЖЕ¶
mallinfo(3), malloc(3), malloc_stats(3), mallopt(3), open_memstream(3)
ЗАМЕЧАНИЯ¶
Эта страница является частью проекта Linux man-pages версии 4.16. Описание проекта, информацию об ошибках и последнюю версию этой страницы можно найти по адресу https://www.kernel.org/doc/man-pages/.
ПЕРЕВОД¶
Русский перевод этой страницы руководства был сделан aereiae <aereiae@gmail.com>, Alexey <a.chepugov@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitriy S. Seregin <dseregin@59.ru>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, ITriskTI <ITriskTI@gmail.com>, Max Is <ismax799@gmail.com>, Yuri Kozlov <yuray@komyakino.ru>, Иван Павлов <pavia00@gmail.com> и Малянов Евгений Викторович <maljanow@outlook.com>
Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.
Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.
15 сентября 2017 г. | GNU |