我希望使用madvise
和malloc
,但始终有相同的错误:
madvise错误:参数无效
我试图使用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错误:参数无效
最佳答案
您对sizeof
的使用是错误的;您只分配了四个字节的内存(size of 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
更新:
另一个问题是malloc()可以给您不对齐的内存(可能是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;
}
输出:
$ ./a.out
optimize_object_size = 1052672
Allocated 1052672 bytes:0
OK
并且alignment请求似乎是特定于linux的:
Linux说明
当前的Linux实现(2.4.0)将此系统调用更多地视为一个命令而不是建议,因此当它不能
按照这个建议做它通常会做的事。(请参阅上面的错误描述。)这是非标准行为。
Linux实现要求地址addr与页面对齐,并且允许长度为零。如果规范中有某些部分
如果指定的地址范围没有映射,那么Linux版本的madvise()会忽略它们并将调用应用到其余部分(但返回ENOMEM from
系统调用。
最后:
我试图使用MADV_DONTDUMP在我的二进制文件中节省一些空间,但它不起作用。
当然,这是没有道理的。Malloc或posix_memalign添加到您的地址空间,使(至少)正在运行的程序的VSIZ更大。对这个空间的处理完全在(内核)内存管理器的控制之下,由程序对特定内存的引用驱动,也许还有madvice的一些提示。
关于c - 如何在madvise中使用malloc并启用MADV_DONTDUMP选项,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46662565/