使用`madvise`将大内存映射归零

Ser*_* L. 8 c mmap virtual-memory

我有以下问题:

我通过分配一大块的存储器(多个GIB)mmapMAP_ANONYMOUS.该块包含一个大的哈希映射,需要时不时地归零.并非整个映射可以在每一轮中使用(并非每个页面都有错误),因此memset不是一个好主意 - 需要太长时间.

快速做到这一点的最佳策略是什么?

madvise(ptr, length, MADV_DONTNEED);
Run Code Online (Sandbox Code Playgroud)

保证我任何后续访问都提供新的空页面?

从Linux man madvise页面:

此调用不会影响应用程序的语义(MADV_DONTNEED除外),但可能会影响其性能.内核可以自由地忽略这些建议.

...

MADV_DONTNEED

对此范围内页面的后续访问将成功,但将导致从底层映射文件(请参阅mmap(2))或零填充按需页面重新加载内存内容,以便在没有基础文件的情况下进行映射.

...

当前的Linux实现(2.4.0)将此系统调用视为命令而不是建议...

或者我是否必须munmap重新重新映射该区域?

它必须在Linux上工作,理想情况下在OS X上具有相同的行为.

R..*_*R.. 8

有一个更容易解决您的问题,相当便携:

mmap(ptr, length, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
Run Code Online (Sandbox Code Playgroud)

由于MAP_FIXED允许因相当任意的特定于实现的原因而失败,memset因此如果返回则返回MAP_FAILED将是可取的.

  • 如果不清楚,想法是重做`mmap()`,MAP_FIXED地址指向先前映射的内存的部分(或整个).根据文档,这将丢弃以前的页面,并映射新的新页面. (3认同)