Provided by: manpages-ru-dev_4.21.0-2_all bug

ИМЯ

       mallopt - задаёт параметры выделения памяти

LIBRARY

       Standard C library (libc, -lc)

СИНТАКСИС

       #include <malloc.h>

       int mallopt(int param, int value);

ОПИСАНИЕ

       Функция  mallopt()  подстраивает параметры, которые управляют поведением функций выделения
       памяти (смотрите malloc(3)). В аргументе param указывается изменяемый параметр, а в  value
       — новое значение этого параметра.

       В param можно указать следующие значения:

       M_ARENA_MAX
              Если  этот  параметр  не  равен  нулю,  то  он  определяет  жёсткое  ограничение на
              максимальное  количество  площадок  (arenas),  которое  можно   создать.   Площадка
              представляет  собой  общий  набор буферов (pool) памяти, который может использовать
              вызов  malloc(3)  (и  подобные)  для  обслуживания  запросов  выделения.   Площадки
              безопасны  в  нитях  и  поэтому  могут  использоваться  при  одновременных запросах
              выделения. Нужно  соблюдать  соотношение  между  количеством  нитей  и  количеством
              площадок.  Чем  больше  площадок,  тем  меньше  состязаний между нитями, но большее
              потребление памяти.

              Значение по умолчанию данного параметра равно 0, то есть ограничение на  количество
              площадок будет определяться по M_ARENA_TEST.

              Этот     параметр     доступен     начиная    с    glibc    2.10    при    указании
              --enable-experimental-malloc, и начиная с glibc 2.15 — по  умолчанию.  В  некоторых
              версиях  механизм  выделения не имел ограничения на количество создаваемых площадок
              (например, в CentOS 5, RHEL 5).

              При использовании более новых версий glibc приложения могут, в  некоторых  случаях,
              встретить  высокую  состязательность при доступе к площадкам. В этих случаях  может
              быть выгодно   увеличить  M_ARENA_MAX  для  соответствия  количеству  нитей.  Такое
              поведение  подобно  стратегиям,  используемым  tcmalloc и jemalloc (например, общие
              наборы буферов выделения для каждой нити).

       M_ARENA_TEST
              Этим  параметром  определяется  значение  на  количество  создаваемых  площадок;  в
              соответствии  с  ним  будут  исследоваться  системные настройки для оценки жёсткого
              ограничения на количество создаваемых площадок  (определение  площадки  смотрите  в
              описании M_ARENA_MAX).

              Вычисленное  жёсткое  ограничение  на  площадки определяется реализацией и, обычно,
              кратно количеству доступных ЦП. После вычисления  жёсткого  ограничения,  результат
              окончательный и ограничивает общее количество площадок.

              Значение   по  умолчанию  для  параметра  M_ARENA_TEST  равно  2  в  системах,  где
              sizeof(long) равно 4; в противном случае значение по умолчанию равно 8.

              Этот    параметр    доступен    начиная    с    glibc     2.10     при     указании
              --enable-experimental-malloc, и начиная с glibc 2.15 — по умолчанию.

              Значение M_ARENA_TEST не используется, если M_ARENA_MAX не равно нулю.

       M_CHECK_ACTION
              Значение  данного  параметра  управляет  тем,  как  glibc действует при обнаружении
              различных программных ошибок  (например,  освобождение  одного  указателя  дважды).
              Поведение glibc задаётся тремя битами (2, 1 и 0) указанного значения:

              Бит 0  Если  этот  бит установлен, то печатается сообщение в stderr с подробностями
                     ошибки. Сообщение начинается со строки «*** glibc detected ***», далее  идёт
                     имя  программы,  имя  функции  выделения  памяти, в которой возникла ошибка,
                     краткое описание ошибки и адрес памяти, где обнаружена ошибка.

              Бит 1  If this bit is set, then, after printing any error message specified by  bit
                     0, the program is terminated by calling abort(3).  Since glibc 2.4, if bit 0
                     is also set, then, between printing the  error  message  and  aborting,  the
                     program  also prints a stack trace in the manner of backtrace(3), and prints
                     the process's memory mapping in the style of /proc/pid/maps (see proc(5)).

              Бит 2 (начиная с glibc 2.4)
                     Этот  бит  учитывается  только  если  установлен  бит  0.  Если  данный  бит
                     установлен,  то  выдаваемое сообщение об ошибке упрощается до имени функции,
                     где обнаружена ошибка и короткого описания ошибки.

              Оставшиеся биты в  value игнорируются.

              Объединяя выше описанное,  получаются  следующие  числовые  значения,  влияющие  на
              M_CHECK_ACTION:

                   0      Игнорировать  условия  ошибки; продолжить выполнение (с неопределенными
                          результатами).

                   1      Вывести подробное сообщение об ошибке и продолжить выполнение.

                   2      Прервать программу.

                   3      Вывести подробное сообщение об ошибке, трассировку стека и  отображения
                          памяти, а затем прервать программу.

                   5      Вывести простое сообщение об ошибке и продолжить выполнение.

                   7      Вывести  простое  сообщение  об ошибке, трассировку стека и отображения
                          памяти, и прервать программу.

              Since glibc 2.3.4, the default value for the M_CHECK_ACTION  parameter  is  3.   In
              glibc 2.3.3 and earlier, the default value is 1.

              Использование  ненулевого  значения  M_CHECK_ACTION  может  быть полезно, так как в
              противном случае падение может случиться позднее и будет сложно отследить  реальную
              причину проблемы.

       M_MMAP_MAX
              Данным  параметром  задаётся  максимальное  количество  запросов выделения, которые
              может одновременно выполнить mmap(2). Этот параметр существует, так как в некоторых
              системах   ограничено   количество   внутренних  таблиц,  используемых  mmap(2),  и
              использование больше определённого количество снижает производительность.

              По умолчанию значение равно 65536; оно не имеет какого-то специального  обоснования
              и  служит  только  как  предохранитель.  Присвоение  этому  параметру  0  отключает
              использование mmap(2) для обслуживания запросов больших выделений.

       M_MMAP_THRESHOLD
              Для выделений, которые больше или равны M_MMAP_THRESHOLD (в байтах) и не могут быть
              получены из списка свободных, то функции выделения памяти вместо mmap(2) используют
              sbrk(2) для увеличения пространства данных программы.

              Выделяемая с помощью mmap(2) память имеет  значительное  преимущество  в  том,  что
              выделенные  блоки  памяти  можно всегда независимо освободить и вернуть системе (по
              сравнению с кучей, которую можно обрезать только, если память свободна в конце).  С
              другой  стороны,  есть  несколько отрицательных моментов при использовании mmap(2):
              освобождённое пространство не  возвращается  в  список  свободного  для  повторного
              выделения  позже;  память  может  траться впустую, так как выделения mmap(2) должны
              быть  кратны  размеру  страницы;  ядро  должно  выполнять  ресурсоёмкую  задачу  по
              обнулению  памяти,  выделяемой через mmap(2). Баланс этих факторов учтён в значении
              по умолчанию для параметра M_MMAP_THRESHOLD — 128*1024.

              Нижний предел данного параметра равен 0. Верхний предел DEFAULT_MMAP_THRESHOLD_MAX:
              512*1024 в 32-битных системах и 4*1024*1024*sizeof(long) в 64-битных системах.

              Note:  Nowadays, glibc uses a dynamic mmap threshold by default.  The initial value
              of the threshold is 128*1024, but when blocks larger than the current threshold and
              less  than  or  equal  to  DEFAULT_MMAP_THRESHOLD_MAX  are  freed, the threshold is
              adjusted upward to the size of the freed block.  When dynamic mmap thresholding  is
              in  effect,  the threshold for trimming the heap is also dynamically adjusted to be
              twice the dynamic mmap threshold.  Dynamic adjustment  of  the  mmap  threshold  is
              disabled if any of the M_TRIM_THRESHOLD, M_TOP_PAD, M_MMAP_THRESHOLD, or M_MMAP_MAX
              parameters is set.

       M_MXFAST (начиная с glibc 2.3)
              Задаёт верхний порог запросов выделения памяти, которые  обрабатываются  с  помощью
              «fastbins»  (значение  параметра  измеряется  в  байтах).  Fastbins  —  это области
              хранилища,  которые  содержат  освобождённые  блоки  памяти  одного  размера  и  не
              объединяют  смежные  свободные  блоки.  Последующее перераспределение блоков одного
              размера при выделении из fastbin может  обрабатываться  очень  быстро,  хотя  из-за
              этого может увеличиться фрагментация памяти и общее количество памяти программы.

              По  умолчанию  значение параметра равно 64*sizeof(size_t)/4 (т. е., 64 на 32-битных
              архитектурах). Диапазон значений параметра: 0 -  80*sizeof(size_t)/4.  Присваивание
              M_MXFAST значения 0 отключает использование fastbins.

       M_PERTURB (начиная с glibc 2.4)
              Если  этому  параметру  присвоено  ненулевое  значение,  то байты выделенной памяти
              (кроме выделенных через calloc(3)) инициализируются дополнением значения в наименее
              значимом  байте  value,  и  при освобождении памяти с помощью free(3) освобождённым
              байтам присваивается значение  наименее  значимого  байта  value.  Это  может  быть
              полезно  для  обнаружения ошибок, когда программа некорректно полагается на то, что
              выделенная памяти инициализируется нулями  или  повторно  использует  значения  уже
              освобождённой памяти.

              Значение по умолчанию для этого параметра равно 0.

       M_TOP_PAD
              Данным  параметром  определяется  количество  заполнения  при  вызове  sbrk(2)  для
              изменения пространства данных программы  (измеряется  в  байтах).  Данный  параметр
              полезен в следующих случаях:

              •  Когда пространство данных программы увеличивается, то M_TOP_PAD байт добавляется
                 к запросу sbrk(2).

              •  Когда  обрезается  куча  в   следствии   вызова   free(3)   (смотрите   описание
                 M_TRIM_THRESHOLD), то это количество пространства предохраняется вверху кучи.

              В  обоих  случаях,  количество  заполнения  всегда округляется до границы системной
              страницы.

              Изменение M_TOP_PAD — компромисс между  увеличением  количества  системных  вызовов
              (если значение параметра занижено) и тратой неиспользуемой памяти сверху кучи (если
              значение параметра завышено).

              Значение по умолчанию этого параметра равно 128*1024.

       M_TRIM_THRESHOLD
              Когда количество непрерывной свободной памяти сверху кучи вырастает до значительных
              размеров  функция  free(3)  вызывает sbrk(2) для освобождения этой памяти обратно в
              систему (это может быть полезно в программах,  которые  работают  длительное  время
              после  освобождения  значительного  количества памяти). Параметром M_TRIM_THRESHOLD
              задаётся минимальный размер (в байтах), которого  должен  достигнуть  блок  памяти,
              чтобы вызвался sbrk(2) для обрезания кучи.

              Значение  по  умолчанию  этого параметра равно 128*1024. Установка M_TRIM_THRESHOLD
              равным -1 отключает обрезку.

              Изменение M_TRIM_THRESHOLD —  компромисс  между  увеличением  количества  системных
              вызовов  (если  значение  параметра занижено) и тратой неиспользуемой памяти сверху
              кучи (если значение параметра завышено).

   Переменные окружения
       Параметры,  управляющие  mallopt(),  можно  изменить   и   через   переменные   окружения.
       Использование  этих  переменных  позволяет  изменять  работу  программы  без пересборки из
       исходного кода. В целях эффективной  работы  эти  переменные  должны  быть  определены  до
       первого вызова функции выделения памяти (если этот же параметр изменяется через mallopt(),
       то вызов mallopt() имеет приоритет). В целях безопасности, эти переменные игнорируются для
       программ с установленными битами set-user-ID и set-group-ID.

       Используются  следующие  переменные  окружения (обратите внимание на подчёркивание в конце
       некоторых переменных):

       MALLOC_ARENA_MAX
              Управляет параметром M_ARENA_MAX, аналогично вызову mallopt().

       MALLOC_ARENA_TEST
              Управляет параметром M_ARENA_TEST, аналогично вызову mallopt().

       MALLOC_CHECK_
              Эта  переменная  окружения  управляет   тем   же   параметром   что   и   mallopt()
              M_CHECK_ACTION.  Если  эта  переменная  установлена  в ненулевое значение, то будет
              использоваться особенная  реализация  функций  выделения  памяти  (это  достигается
              использованием  функции  malloc_hook(3)).  Эта  реализация выполняет дополнительные
              проверки ошибок, но она медленнее чем стандартный набор  функций  выделения  памяти
              (эта  реализация не способна обнаружить все возможные ошибки; утечки памяти всё ещё
              возможны).

              Значение, назначенное этой переменной окружения должно быть  одиночной  цифрой;  их
              значения описаны в M_CHECK_ACTION. Все символы кроме первой цифры игнорируются.

              В  целях  безопасности  по  умолчанию  переменная  MALLOC_CHECK_  игнорируется  для
              программ  с  установленными  битами  set-user-ID  и  set-group-ID.   Однако,   если
              существует  файл  /etc/suid-debug  (содержимое  файла  не  важно), то MALLOC_CHECK_
              учитывается и для программ с установленными битами set-user-ID и set-group-ID.

       MALLOC_MMAP_MAX_
              Управляет параметром M_MMAP_MAX, аналогично вызову mallopt().

       MALLOC_MMAP_THRESHOLD_
              Управляет параметром M_MMAP_THRESHOLD, аналогично вызову mallopt().

       MALLOC_PERTURB_
              Управляет параметром M_PERTURB, аналогично вызову mallopt().

       MALLOC_TRIM_THRESHOLD_
              Управляет параметром M_TRIM_THRESHOLD, аналогично вызову mallopt().

       MALLOC_TOP_PAD_
              Управляет параметром M_TOP_PAD, аналогично вызову mallopt().

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

       При успешном выполнении mallopt() возвращается 1. При ошибке возвращается 0.

ОШИБКИ

       При ошибке значение errno не изменяется.

СТАНДАРТЫ

       Данная  функция  не  описана  в  POSIX  или  C.  Подобная  функция  существует  во  многих
       ответвлениях  System  V,  но  значения  param  не  совпадают.  В SVID определены параметры
       M_MXFAST, M_NLBLKS, M_GRAIN и M_KEEP, но только первый из них реализован в glibc.

ДЕФЕКТЫ

       Неправильное значение param не вызывает ошибки.

       Ошибка вычисления внутри реализации glibc означает, что вызов:

           mallopt(M_MXFAST, n)

       не приведёт к тому, что из fastbins будет  выделяться  память  до  размера  n.  Чтобы  это
       сработало,   n  должно  быть  округлено  до  следующего  множителя  большего  или  равного
       (2k+1)*sizeof(size_t), где k — целое число.

       Если mallopt() используется для установки M_PERTURB, то, как и ожидалось, байты  свободной
       памяти  инициализируются  дополнением  байта  из  value, и когда эта память освобождается,
       байты области инициализируются байтом, указанным в value. Однако, в реализации есть ошибка
       выхода  за sizeof(size_t): вместо инициализации точного блока памяти освобождаемом вызовом
       free(p), блок начинает инициализироваться с p+sizeof(size_t).

ПРИМЕРЫ

       Представленная далее программа показывает  использование  M_CHECK_ACTION.  Если  программе
       передаётся  аргумент  командной  строки  (целое  число), то этот аргумент используется для
       установки значения параметра M_CHECK_ACTION. При этом программа  выделяет  блок  памяти  и
       освобождает его дважды (ошибка).

       Следующий  сеанс  в  оболочке показывает работу программы с glibc и значением по умолчанию
       для M_CHECK_ACTION:

           $ ./a.out
           main(): возвращение из первого вызова free()
           *** glibc detected *** ./a.out: double free or corruption (top): 0x09d30008 ***
           ======= Backtrace: =========
           /lib/libc.so.6(+0x6c501)[0x523501]
           /lib/libc.so.6(+0x6dd70)[0x524d70]
           /lib/libc.so.6(cfree+0x6d)[0x527e5d]
           ./a.out[0x80485db]
           /lib/libc.so.6(__libc_start_main+0xe7)[0x4cdce7]
           ./a.out[0x8048471]
           ======= Memory map: ========
           001e4000-001fe000 r-xp 00000000 08:06 1083555    /lib/libgcc_s.so.1
           001fe000-001ff000 r--p 00019000 08:06 1083555    /lib/libgcc_s.so.1
           [some lines omitted]
           b7814000-b7817000 rw-p 00000000 00:00 0
           bff53000-bff74000 rw-p 00000000 00:00 0          [stack]
           Aborted (core dumped)

       В этом запуске показаны результаты при других значениях M_CHECK_ACTION:

           $ ./a.out 1             # показ ошибки и продолжение
           main(): возвращение из первого вызова free()
           *** glibc detected *** ./a.out: double free or corruption (top): 0x09cbe008 ***
           main(): возвращение из второго вызова free()
           $ ./a.out 2             # прерывание без показа ошибки
           main(): возвращение из первого вызова free()
           Aborted (core dumped)
           $ ./a.out 0             # игнорирование ошибки и продолжение
           main(): возвращение из первого вызова free()
           main(): возвращение из второго вызова free()

       При этом запуске показано как изменить тот же  параметр  с  помощью  переменной  окружения
       MALLOC_CHECK_:

           $ MALLOC_CHECK_=1 ./a.out
           main(): возвращение из первого вызова free()
           *** glibc detected *** ./a.out: free(): invalid pointer: 0x092c2008 ***
           main(): возвращение из второго вызова free()

   Исходный код программы

       #include <malloc.h>
       #include <stdio.h>
       #include <stdlib.h>

       int
       main(int argc, char *argv[])
       {
           char *p;

           if (argc > 1) {
               if (mallopt(M_CHECK_ACTION, atoi(argv[1])) != 1) {
                   fprintf(stderr, "mallopt() завершилась с ошибкой");
                   exit(EXIT_FAILURE);
               }
           }

           p = malloc(1000);
           if (p == NULL) {
               fprintf(stderr, "malloc() завершилась с ошибкой");
               exit(EXIT_FAILURE);
           }

           free(p);
           printf("%s(): returned from first free() call\n", __func__);

           free(p);
           printf("%s(): returned from second free() call\n", __func__);

           exit(EXIT_SUCCESS);
       }

СМ. ТАКЖЕ

       mmap(2), sbrk(2), mallinfo(3), malloc(3), malloc_hook(3), malloc_info(3), malloc_stats(3),
       malloc_trim(3), mcheck(3), mtrace(3), posix_memalign(3)

ПЕРЕВОД

       Русский перевод этой страницы руководства был сделан 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 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте
       электронное письмо на ⟨man-pages-ru-talks@lists.sourceforge.net⟩.