如何在madvise中使用malloc并启用MADV_DONTDUMP选项 [英] How to use malloc with madvise and enable MADV_DONTDUMP option
问题描述
我正在尝试使用 madvise
和 malloc
,但是我总是遇到相同的错误:
madvise错误:参数无效
我试图使用 MADV_DONTDUMP
在我的二进制文件中节省一些空间,但是没有用.
页面大小为4096.
int main(int argc,char * argv []){无效* p_optimize_object;unsigned intoptimize_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);如果(madvise(p_optimize_object,optimize_object_size,MADV_DONTDUMP | MADV_SEQUENTIAL)== -1){perror("madvise错误");}printf("OK \ n");返回0;}
这是命令:
$ gcc -g -O3 madvice.c&&./a.out
输出:
madvise错误:参数无效
您对 sizeof
的使用是错误的;您只分配了四个字节的内存(sizeof unsigned int),并为同一块内存调用了大小参数为1M的madvise().
#include< stdio.h>#include< stdlib.h>#include< sys/mman.h>int main(int argc,char * argv []){无效* p_optimize_object;unsigned intoptimize_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,已分配%zu字节\ n",sizeof(optimize_object_size));如果(madvise(p_optimize_object,optimize_object_size,MADV_WILLNEED | MADV_SEQUENTIAL)== -1){perror("madvise错误");}printf("OK \ n");返回0;}
输出:
optimize_object_size = 1052672分配了4个字节madvise错误:参数无效好的
更新:
另一个问题是malloc()可以为您提供未对齐的内存(可能具有4,8,16,...的对齐方式),其中madvice()需要页面对齐的内存:
#include< stdio.h>#include< stdlib.h>#include< sys/mman.h>int main(int argc,char * argv []){无效* p_optimize_object;unsigned intoptimize_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 0p_optimize_object = malloc(sizeof(optimize_object_size));fprintf(stderr,已分配%zu字节\ n",sizeof(optimize_object_size));#elif 0p_optimize_object = malloc(optimize_object_size);fprintf(stderr,已分配%zu个字节\ n",optimize_object_size);#别的rc = posix_memalign(& p_optimize_object,4096,optimize_object_size);fprintf(stderr,已分配%zu字节:%d \ n",optimize_object_size,rc);#万一//如果(madvise(p_optimize_object,optimize_object_size,MADV_WILLNEED | MADV_SEQUENTIAL)== -1)如果(madvise(p_optimize_object,optimize_object_size,MADV_WILLNEED | MADV_DONTFORK)== -1){perror("madvise错误");}printf("OK \ n");返回0;}
输出:
$ ./a.outoptimize_object_size = 1052672分配1052672字节:0好的
并且对齐要求似乎是特定于linux的:
Linux 笔记当前的Linux实现(2.4.0)将此系统调用更多地视为命令而不是建议,因此,当它不能执行时,可能会返回错误.做它通常会做的事情来回应这个建议.(请参阅上面的错误说明.)这是非标准行为.
Linux实现要求地址addr进行页面对齐,并允许长度为零.如果规范中有某些部分未映射的固定地址范围,Linux版本的madvise()会忽略它们,并将调用应用于其余部分(但会从以下位置返回ENOMEM:系统调用).
最后:
我试图使用MADV_DONTDUMP在我的二进制文件中节省一些空间,但是没有用.
当然,这没有任何意义.Malloc或posix_memalign添加到您的地址空间,使(至少)正在运行的程序的VSIZ更大.这个空间所发生的一切完全由(内核)内存管理器掌握,由程序对特定内存的引用驱动,而也许 madvice给出了一些提示.
I'm looking to use madvise
and malloc
but I have always the same error:
madvise error: Invalid argument
I tried to use the MADV_DONTDUMP
to save some space in my binaries but it didn't work.
The page size is 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;
}
Here's the command:
$ gcc -g -O3 madvice.c && ./a.out
Output:
madvise error: Invalid argument
Your usage of sizeof
is wrong; you are allocating only four bytes of memory (sizeof unsigned int), and calling madvise() with a size argument of 1M for the same chunk of memory.
#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;
}
Output:
optimize_object_size = 1052672
Allocated 4 bytes
madvise error: Invalid argument
OK
UPDATE:
And the other problem is that malloc() can give you non-aligned memory (probably with an alignment of 4,8,16,...), where madvice() wants page-aligned memory:
#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
And the alignement requerement appears to be linux-specific:
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).
Finally:
I tried to use the MADV_DONTDUMP to save some space in my binaries but it didn't work.
Which, of course, doesn't make sense. Malloc or posix_memalign add to your address space, making (at least) the VSIZ of your running program larger. What happens to the this space is completely in the hands of the (kernel) memory manager, driven by your program's references to the particular memory, with maybe a few hints from madvice.
这篇关于如何在madvise中使用malloc并启用MADV_DONTDUMP选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!