MALLOPT - Linux手册页
Linux程序员手册 第3部分
更新日期: 2020-06-09
名称
mallopt-设置内存分配参数
语法
#包括
int mallopt(int参数,int值);
说明
mallopt()函数调整用于控制内存分配函数行为的参数(请参阅malloc(3))。 param参数指定要修改的参数,而value指定该参数的新值。
可以为参数指定以下值:
- M_ARENA_MAX
- 如果此参数具有非零值,则它将对可以创建的最大竞技场数量定义硬限制。舞台表示一个内存池,可以由malloc(3)(及类似)对服务分配请求的调用使用。 Arenas是线程安全的,因此可能有多个并发内存请求。权衡是线程数和竞技场数之间。您拥有的竞技场越多,每个线程的争用越少,但是内存使用率越高。
- 该参数的默认值为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。)
- 竞技场硬限制的计算是实现定义的,通常以可用CPU数量的倍数计算。一旦计算出硬限制,结果就是最终的,并限制了竞技场的总数。
- 在sizeof(long)为4的系统上,M_ARENA_TEST参数的默认值为2;否则默认值为8。
- 从glibc 2.10开始通过--enable-experimental-malloc提供了此参数,并且从glibc 2.15开始默认可用。
- 当M_ARENA_MAX具有非零值时,不使用M_ARENA_TEST的值。
- M_CHECK_ACTION
- Setting this parameter controls how glibc responds when various kinds
of programming errors are detected (e.g., freeing the same pointer twice).
The 3 least significant bits (2, 1, and 0) of the value assigned
to this parameter determine the glibc behavior, as follows:
- Bit 0
- 如果设置了此位,则在stderr上打印一条单行消息,其中提供有关错误的详细信息。该消息以字符串" *** glibc检测到***"开头,其后是程序名称,检测到错误的内存分配函数的名称,错误的简要说明以及内存地址,其中检测到错误。
- Bit 1
- 如果设置了此位,则在打印由位0指定的任何错误消息之后,将通过调用abort(3)终止程序。在从2.4开始的glibc版本中,如果还设置了位0,则在打印错误消息和中止操作之间,程序还将以backtrace(3)的方式打印堆栈跟踪,并以/样式打印进程的内存映射proc / [pid] / maps(请参阅proc(5))。
- Bit 2 (since glibc 2.4)
- 仅当还设置了位0时,该位才有效。如果设置了此位,则描述错误的单行消息将简化为仅包含检测到错误的函数的名称以及错误的简短描述。
- 值中的其余位将被忽略。
- Combining the above details,
the following numeric values are meaningful for
M_CHECK_ACTION:
- 0
- 忽略错误条件;继续执行(结果不确定)。
- 1
- 打印详细的错误消息并继续执行。
- 2
- 中止程序。
- 3
- 打印详细的错误消息,堆栈跟踪和内存映射,然后中止程序。
- 5
- 打印一个简单的错误消息并继续执行。
- 7
- 打印简单错误消息,堆栈跟踪和内存映射,然后中止程序。
- 从glibc 2.3.4开始,M_CHECK_ACTION参数的默认值为3。在glibc 2.3.3和更低版本中,默认值为1。
- 使用非零的M_CHECK_ACTION值可能会很有用,因为否则可能会在以后发生崩溃,因此很难找出问题的真正原因。
- M_MMAP_MAX
- 此参数指定可以使用mmap(2)同时处理的分配请求的最大数量。此参数存在是因为某些系统的内部表供mmap(2)使用的数量有限,并且使用多个表可能会降低性能。
- 默认值为65,536,该值没有特殊意义,仅用作保护措施。将此参数设置为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:在32位系统上为512 * 1024,在64位系统上为4 * 1024 * 1024 * sizeof(long)。
- 注意:如今,glibc默认使用动态mmap阈值。阈值的初始值为128 * 1024,但是当释放大于当前阈值且小于或等于DEFAULT_MMAP_THRESHOLD_MAX的块时,将阈值向上调整为释放块的大小。当动态mmap阈值生效时,修剪堆的阈值也会动态调整为动态mmap阈值的两倍。如果设置了M_TRIM_THRESHOLD,M_TOP_PAD,M_MMAP_THRESHOLD或M_MMAP_MAX参数中的任何一个,则将禁用mmap阈值的动态调整。
- M_MXFAST(since glibc 2.3)
- 设置使用" fastbins"满足的内存分配请求的上限。 (此参数的度量单位为字节。)快速存储区是存储相同大小的已释放内存块的存储区域,而不合并相邻的空闲块。尽管可以增加程序的内存碎片和整体内存占用量,但是通过快速bin分配可以很快处理相同大小的块。
- 此参数的默认值为64 * sizeof(size_t)/ 4(即32位体系结构上为64)。此参数的范围是0到80 * sizeof(size_t)/ 4。将M_MXFAST设置为0将禁用快速bins。
- M_PERTURB(since glibc 2.4)
- 如果此参数设置为非零值,则分配的内存字节(通过calloc(3)分配的内存除外)将初始化为value的最低有效字节中的值的补码,并在使用free( 3),将释放的字节设置为值的最低有效字节。这对于在程序错误地依赖于已分配的内存初始化为零的错误检测错误或重新使用已释放的内存中的值很有用。
- 此参数的默认值为0。
- M_TOP_PAD
- This parameter defines the amount of padding to employ when calling
sbrk(2)
to modify the program break.
(The measurement unit for this parameter is bytes.)
This parameter has an effect in the following circumstances: - 在这两种情况下,填充量总是四舍五入到系统页面边界。
- 修改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是在增加系统调用数量(将参数设置为低时)与浪费堆顶部(未将参数设置为高)时未使用的内存之间的权衡。
Environment variables
可以定义许多环境变量来修改与mallopt()控制的参数相同的一些参数。使用这些变量的优点是不需要更改程序的源代码。为了有效,必须在第一次调用内存分配函数之前定义这些变量。 (如果通过mallopt()调整了相同的参数,则mallopt()设置优先。)出于安全原因,在set-user-ID和set-group-ID程序中将忽略这些变量。
环境变量如下(请注意,某些变量名称的末尾带有下划线):
- MALLOC_ARENA_MAX
- 控制与mallopt()M_ARENA_MAX相同的参数。
- MALLOC_ARENA_TEST
- 控制与mallopt()M_ARENA_TEST相同的参数。
- MALLOC_CHECK_
- 此环境变量控制与mallopt()M_CHECK_ACTION相同的参数。如果将此变量设置为非零值,则使用内存分配功能的特殊实现。 (这是使用malloc_hook(3)功能完成的。)此实现执行附加的错误检查,但比标准的内存分配函数集慢。 (此实现未检测到所有可能的错误;仍然可能发生内存泄漏。)
- 分配给该环境变量的值应为一位,其含义如M_CHECK_ACTION所述。超出起始数字的任何字符都将被忽略。
- 出于安全原因,默认情况下,对set-user-ID和set-group-ID程序禁用MALLOC_CHECK_的作用。但是,如果文件/ etc / suid-debug存在(文件的内容无关),则MALLOC_CHECK_对set-user-ID和set-group-ID程序也有影响。
- MALLOC_MMAP_MAX_
- 控制与mallopt()M_MMAP_MAX相同的参数。
- MALLOC_MMAP_THRESHOLD_
- 与mallopt()M_MMAP_THRESHOLD控制相同的参数。
- MALLOC_PERTURB_
- 控制与mallopt()M_PERTURB相同的参数。
- MALLOC_TRIM_THRESHOLD_
- 与mallopt()M_TRIM_THRESHOLD控制相同的参数。
- MALLOC_TOP_PAD_
- 与mallopt()M_TOP_PAD控制相同的参数。
返回值
成功时,mallopt()返回1。错误时,返回0。
错误说明
错误时,未设置errno。
遵循规范
POSIX或C标准未指定此功能。许多System V派生类中都存在类似的功能,但是param的值范围随系统而异。 SVID定义了选项M_MXFAST,M_NLBLKS,M_GRAIN和M_KEEP,但是只有第一个选项在glibc中实现。
BUGS
为参数指定无效值不会产生错误。
glibc实现中的计算错误意味着调用形式为:
mallopt(M_MXFAST, n)
不会导致将fastbin用于大小最大为n的所有分配。为了确保获得期望的结果,n应该四舍五入为大于或等于(2k + 1)* sizeof(size_t)的下一个倍数,其中k为整数。
如果使用mallopt()设置M_PERTURB,则按预期方式,将分配的内存字节初始化为值中字节的补码,并在释放该内存时,将区域的字节初始化为中指定的字节。值。但是,在实现中存在一个按sizeof(size_t)偏移的错误:不是完全初始化由调用free(p)释放的内存块,而是初始化了以p + sizeof(size_t)开始的块。
示例
下面的程序演示了M_CHECK_ACTION的用法。如果程序提供了(整数)命令行参数,则该参数用于设置M_CHECK_ACTION参数。然后,程序分配一个内存块,并将其释放两次(错误)。
以下shell会话显示了在glibc下运行该程序时的情况,默认值为M_CHECK_ACTION:
$ ./a.out main(): returned from first free() call *** 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 # Diagnose error and continue main(): returned from first free() call *** glibc detected *** ./a.out: double free or corruption (top): 0x09cbe008 *** main(): returned from second free() call $ ./a.out 2 # Abort without error message main(): returned from first free() call Aborted (core dumped) $ ./a.out 0 # Ignore error and continue main(): returned from first free() call main(): returned from second free() call
下一次运行展示了如何使用MALLOC_CHECK_环境变量设置相同的参数:
$ MALLOC_CHECK_=1 ./a.out main(): returned from first free() call *** glibc detected *** ./a.out: free(): invalid pointer: 0x092c2008 *** main(): returned from second free() call
Program source
#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() failed"); exit(EXIT_FAILURE); } } p = malloc(1000); if (p == NULL) { fprintf(stderr, "malloc() failed"); exit(EXIT_FAILURE); } free(p); printf("main(): returned from first free() call\n"); free(p); printf("main(): returned from second free() call\n"); 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)
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。