首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将malloc与with一起使用并启用MADV_DONTDUMP选项

如何将malloc与with一起使用并启用MADV_DONTDUMP选项
EN

Stack Overflow用户
提问于 2017-10-10 08:58:23
回答 3查看 2.1K关注 0票数 0

我希望使用madvisemalloc,但我总是有相同的错误:

建议错误:无效参数

我试图使用MADV_DONTDUMP在我的二进制文件中节省一些空间,但是它没有工作。

页面大小为4096。

代码语言:javascript
复制
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;
}

以下是命令:

代码语言:javascript
复制
$ gcc -g -O3 madvice.c  && ./a.out

输出:

建议错误:无效参数

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-10-10 09:33:14

您使用sizeof是错误的;您只分配了四个字节的内存(无符号int的大小),并为相同的内存块调用大小参数为1M的m吉()。

代码语言:javascript
复制
#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;
}

输出:

代码语言:javascript
复制
optimize_object_size = 1052672
Allocated 4 bytes
madvise error: Invalid argument
OK

更新:

另一个问题是malloc()可以为您提供非对齐内存(可能是4,8,16,.),其中madvice()需要对页对齐的内存:

代码语言:javascript
复制
#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;
}

产出:

代码语言:javascript
复制
$ ./a.out
optimize_object_size = 1052672
Allocated 1052672 bytes:0
OK

对齐请求似乎是特定于linux的:

Linux当前的Linux实现(2.4.0)认为,这个系统调用更多的是作为一个命令,而不是作为通知,因此,当它无法执行通常响应此通知的操作时,可能会返回一个错误。(请参阅上面的错误描述。)这是不规范的行为。 Linux实现要求地址addr对齐页,并允许长度为零。如果没有映射特定地址范围的某些部分,则Linux版本的m吉()将忽略这些部分并将调用应用到其余部分(但将从系统调用中返回ENOMEM,这是应该的)。

最后:

我试图使用MADV_DONTDUMP在我的二进制文件中节省一些空间,但是它没有工作。

当然,这是没有道理的。Malloc或posix_memalign添加到您的地址空间,(至少)使您正在运行的程序的VSIZ更大。这个空间所发生的一切完全掌握在(内核)内存管理器的手中,由程序对特定内存的引用驱动,其中可能有一些来自madvice的提示。

票数 1
EN

Stack Overflow用户

发布于 2017-10-10 09:18:31

您不能这样做,即使在某些情况下可以使用某些标志(您试图在这里使用的标志应该相对无害),您也不应该这样做。madvise对内存的操作级别低于malloc给您的级别,而干扰malloc中的内存很可能会破坏malloc。

如果您想要一些可以调用madvise的内存块,您应该使用mmap来获得它。

票数 2
EN

Stack Overflow用户

发布于 2017-10-10 10:35:42

我试图使用MADV_DONTDUMP在我的二进制文件中节省一些空间,但是它没有工作。

再次阅读,并更仔细地阅读madvise(2) man页面。

地址应该是对齐的。malloc的结果通常不是对页对齐(页面大小通常为4K字节,但SC_PAGESIZE请参见sysconf(3) )。使用mmap(2)在您的虚拟地址空间中请求页面对齐段。

,您不会在二进制可执行文件中保存任何空间。您只需在核心转储中节省空间,请参阅核心(5)。核心转储也不应该发生。参见信号(7) (也可以阅读关于分段故障未定义行为的文章)。

要禁用核心转储,可以考虑使用极限(2)RLIMIT_CORE (或者运行bash shell的终端中的ulimit -c 巴什积木 )。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46662565

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档