如何在madvise中使用malloc并启用MADV_DONTDUMP选项 [英] How to use malloc with madvise and enable MADV_DONTDUMP option

查看:146
本文介绍了如何在madvise中使用malloc并启用MADV_DONTDUMP选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆