You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何扩大mmap()分配的内存区域且保留其起始地址与原有内容

结论

可以实现,使用Linux的mremap系统调用即可,该调用专门用于调整已存在mmap映射区域的大小,默认会保留原有内存区域的所有内容,也可以通过标志位要求内核保留原映射的起始地址。

ARM64架构下的实现说明

你当前使用的是ARM64指令集的系统调用规范,mremap的参数对应寄存器、调用方法如下:

调用参数说明

  • x0:传入原有mmap调用返回的内存区域起始地址(注意你必须提前保存好mmap调用成功后x0里的地址值)
  • x1:原有内存区域的大小,这里你之前分配的是4096,直接填入即可
  • x2:调整后的新内存区域总大小,比如你要扩大到8KB就填入8192
  • x3:控制标志:
    • 填MREMAP_MAYMOVE(值为1):允许内核在原地址后没有足够连续空间时,将整个映射迁移到其他地址,原有内容会完整保留,返回新的地址
    • 填MREMAP_MAYMOVE | MREMAP_FIXED(值为3):强制要求内核必须保留原起始地址,如果原地址后没有足够空间则直接调用失败
  • x8:mremap的ARM64系统调用号为223

示例汇编代码

; 假设之前mmap返回的起始地址已经存在x9寄存器里(你需要自行保存该值)
        mov     x0, x9                  ; 传入原映射起始地址
        mov     x1, 4096                ; 原有映射的大小
        mov     x2, 8192                ; 扩大后的总大小,示例为8KB
        mov     x3, 1                   ; MREMAP_MAYMOVE,允许必要时迁移地址
        mov     x8, 223                 ; mremap系统调用号
        svc     0

        ; 调用结果判断:如果x0为负值,代表调用出错,错误码为-x0

注意事项

  • 如果你强制要求保留原地址,需要确保原映射区域之后的连续虚拟地址空间没有被其他映射占用,否则mremap会返回-ENOMEM错误
  • 调用成功后,新的内存区域起始地址会返回在x0寄存器中,后续操作需要使用这个新地址(如果没有迁移的话就和你传入的原地址一致)
  • 扩大后的内存区域新增的部分和原有匿名映射的规则一致,初始内容为0

内容的提问来源于stack exchange,提问作者Alexander Zhak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 05:15:05