如何使用malloc用的madvise并启用MADV_DONTDUMP选项
我期待使用madvise
和malloc
但我总是相同的错误:如何使用malloc用的madvise并启用MADV_DONTDUMP选项
madvise error: Invalid argument
我试图用MADV_DONTDUMP
节省一些空间,我的二进制文件但它不起作用。
页面大小是4096
int main(int argc, char *argv[])
{
void *p_optimize_object;
unsigned int optimize_object_size = 4096*256;
optimize_object_size = ((optimize_object_size/4096) + 1) * 4096;
printf("optimize_object_size = %d\n", optimize_object_size);
p_optimize_object = malloc(optimize_object_size);
if (madvise(p_optimize_object, optimize_object_size, MADV_DONTDUMP | MADV_SEQUENTIAL) == -1)
{
perror("madvise error");
}
printf("OK\n");
return 0;
}
这里的命令:
$ gcc -g -O3 madvice.c && ./a.out
输出:
madvise error: Invalid argument
您对sizeof
的使用是错误的;您只分配四个字节的内存(sizeof unsigned int),并为大小相同的内存块调用1M大小参数的madvise()。
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
int main(int argc, char *argv[])
{
void *p_optimize_object;
unsigned int optimize_object_size = 4096*256;
optimize_object_size = ((optimize_object_size/4096) + 1) * 4096;
printf("optimize_object_size = %d\n", optimize_object_size);
p_optimize_object = malloc(sizeof(optimize_object_size));
fprintf(stderr, "Allocated %zu bytes\n", sizeof(optimize_object_size));
if (madvise(p_optimize_object, optimize_object_size, MADV_WILLNEED | MADV_SEQUENTIAL) == -1)
{
perror("madvise error");
}
printf("OK\n");
return 0;
}
输出:
optimize_object_size = 1052672
Allocated 4 bytes
madvise error: Invalid argument
OK
UPDATE:
而另一个问题是,malloc()函数可以给你非ALIG斯内德内存(可能与4,8,16对齐,...)),其中madvice(要页对齐的内存:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
int main(int argc, char *argv[])
{
void *p_optimize_object;
unsigned int optimize_object_size = 4096*256;
int rc;
optimize_object_size = ((optimize_object_size/4096) + 1) * 4096;
printf("optimize_object_size = %d\n", optimize_object_size);
#if 0
p_optimize_object = malloc(sizeof(optimize_object_size));
fprintf(stderr, "Allocated %zu bytes\n", sizeof(optimize_object_size));
#elif 0
p_optimize_object = malloc(optimize_object_size);
fprintf(stderr, "Allocated %zu bytes\n", optimize_object_size);
#else
rc = posix_memalign (&p_optimize_object, 4096, optimize_object_size);
fprintf(stderr, "Allocated %zu bytes:%d\n", optimize_object_size, rc);
#endif
// if (madvise(p_optimize_object, optimize_object_size, MADV_WILLNEED | MADV_SEQUENTIAL) == -1)
if (madvise(p_optimize_object, optimize_object_size, MADV_WILLNEED | MADV_DONTFORK) == -1)
{
perror("madvise error");
}
printf("OK\n");
return 0;
}
OUTPUT:
$ ./a.out
optimize_object_size = 1052672
Allocated 1052672 bytes:0
OK
并且alignement requerement似乎是linux特有的:
Linux Notes The current Linux implementation (2.4.0) views this system call more as a command than as advice and hence may return an error when it cannot do what it usually would do in response to this advice. (See the ERRORS description above.) This is non-standard behavior.
The Linux implementation requires that the address addr be page-aligned, and allows length to be zero. If there are some parts of the speci‐ fied address range that are not mapped, the Linux version of madvise() ignores them and applies the call to the rest (but returns ENOMEM from the system call, as it should).
最后:
I tried to use the MADV_DONTDUMP to save some space in my binaries but it didn't work.
其中,当然,没有任何意义。 Malloc或posix_memalign将添加到您的地址空间,从而使(至少)正在运行的程序的VSIZ变大。这个空间发生的事情完全掌握在(内核)内存管理器的手中,由程序对特定内存的引用驱动,也许是从madvice提供的一些提示。
你不能,甚至如果你能做到这一点在一定有特定标志的情况(以及你在这里尝试使用的标志应该是相对无害的),你不应该这样做。 madvise
从低级别分配的内存操作比malloc
给你和搞乱从malloc的内存将可能破坏malloc。
如果你想要一些可以调用madvise
的内存块,你应该使用mmap
来获得它。
I tried to use the
MADV_DONTDUMP
to save some space in my binaries but it didn't work.
再次阅读,并更仔细的madvise(2)man
页面。
该地址应该页面对齐。 malloc
的结果通常不是页面对齐的(页面大小通常为4K字节,但对于SC_PAGESIZE
,请参阅sysconf(3))。使用mmap(2)要求您的virtual address space中的页面对齐段。
您不会在您的二进制文件executable中保存任何空间。您只需在核心转储中节省空间,请参阅core(5)。 核心转储不应该发生。请参阅signal(7)(还请阅读有关segmentation fault和undefined behaviour)。
要禁用核心转储,而考虑用setrlimit(2)RLIMIT_CORE
(或ulimit -c
bash builtin在终端上运行的bash
壳)。
你知道'sizeof(optimize_object_size)'最可能等于4吗? – joop
如果已经给出答案,请不要更正您的问题;这会使(否则是正确的)答案失效。 – joop