mmap中允许合并页面吗?

埃里克·斯托奇

简而言之,我想调整内存大小,但将旧内存放在新内存的中间。

所以我所做的就是利用mmap初始大小(p1),mmap在地址前p1假装我所做的内存更大,然后把新的指针,如果我有一个创建它mmapp3mremap)。该代码似乎可以正常工作,但是我不确定这是否应该做。如果不是,我应该如何创建更多内存并将旧的/当前的内存放在其中?

#include <sys/mman.h>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <cerrno>
int main()
{
    auto p1 = (char*) mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
    if (!p1 || p1==(char*)-1)
        return -1;

    auto p1_32 = (int *)p1;
    memset(p1, 0, 4096);
    p1_32[5] = 1035;

    auto p2 = mmap(p1-4096, 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
    if (!p2 || p2==(void*)-1)
        return -2;

    auto p2_32 = (int *)p2;
    memset(p2, 0, 4096);
    p2_32[5] = 5301;

    assert(p2_32[1024+5] == 1035);

    auto p3 = mremap(p2, 4096*2, 4096*4, MREMAP_MAYMOVE);
    if (p3==(char*)-1)
    {
        printf("Errno %d\n", errno);
        return -2;
    }
    auto p3_32 = (int*)p3;

    assert(p3_32[5] == 5301);
    assert(p3_32[1024+5] == 1035);

    printf("Is this correct?\n");
    return 0;
}
史黛西女孩

如上所述这里

munmap()功能将删除整个页面的所有映射,这些映射包含进程地址空间的任何部分,从字节开始addr并继续len字节。

因此可以通过一次munmap调用删除多个映射(就像是单个映射一样)。

但是,您的代码存在问题:如何知道是否未使用页面(p2)之前的页面(p1)?程序的其他参数(包括malloc可能已经分配了它,通过这样使用,MAP_FIXED您将重写(重新映射)其内容:

MAP_FIXED在flags参数中设置了when时,将通知实现,pa的值应为addr如果MAP_FIXED设置为,则mmap()可以返回MAP_FAILED并设置errno[EINVAL]如果MAP_FIXED请求成功,则由建立的映射mmap()将替换range内该进程页面的所有先前映射[pa,pa+len)

因此,我认为这种技巧在一般情况下不会有用,您应该使用它mremap

至于实现的方式:Linux确实合并了顺序私有匿名映射,因此两者都将被合并到vma_struct内核中的一个中。此“功能”具有不良的副作用,例如munmap无法使用释放内存ENOMEM但这更多是实现细节,而不是您可以控制的东西。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在wordpress页面中允许php

我可以在使用htaccess的动态加载页面中允许URL中的连字符吗?

ngOnInit 中允许角订阅吗?

在magento中允许创建新的phtml吗?

文件命名中允许使用@符号吗?

Mercurial INI (hgrc) ui“合并”选项中允许什么?

AutoCloseable合同:写入close()中允许的资源吗?

SVG文档中允许使用多个def吗?

我可以在共享结构中允许任意字段吗?

Python IDLE中允许缩进不正确吗?

javascript属性名称中允许使用破折号吗?

#error指令中允许使用非拉丁字符吗?

C ++ 20中允许使用constexpr / constinit / consteval吗?

在Dart中允许循环进入内部吗?

MQTT主题中允许使用多个#吗?

docker-compose文件中允许使用Go模板吗?

libstdc ++中允许使用不兼容的函数类型吗?

URL中允许的字符

在 NodeJS 中允许 CORS

如何在免费的jqgrid传呼机中允许转到指定页面

我可以控制何时在TabLayout / ViewPager应用程序中允许滑动吗?

HTML4中允许没有值的属性吗?

Hilt Android 可以在不同的活动中允许不同的视图模型实例吗?

以编程方式在行中允许两个成对的TextView与多行TextView重叠吗?

chrome 扩展程序可以监控清单文件中允许域的安全 cookie 吗?

HTTP:主机标头字段中允许使用IP地址吗?

在多表联接中允许空值/重复数据删除吗?T-SQL

如何从PHP数组中获取数据?数组键中允许使用货币符号吗?

在Django网址中允许冒号