【问题标题】:mmap with /dev/zero使用 /dev/zero 的 mmap
【发布时间】:2012-01-20 10:22:07
【问题描述】:

假设我使用 /dev/zero 使用 mmap 分配了一个大内存(40MB),如下所示。

fd = open("/dev/zero", O_RDWR); 
a = mmap (0, 4096e4, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FILE, fd, 0);

我的理解是,当页面被带入物理内存时,内核会将内存初始化为零(我想现代 Linux 内核使用按需分页)。因此,例如,当第一页被触摸并因此被带入物理内存时,内核会将其所有 4096 字节初始化为零,然后当第二页被触摸时,它也会这样做,依此类推。

我的理解正确吗?

【问题讨论】:

  • 只要触摸意味着写,是的。否则,如果你只是从零页读取,实际上只有一个零页,它会在第一次写入时被 COW'ed。
  • 这在 Android 5.0 上会失败,因为 SELinux 会阻止这种奇怪的事情。这就是 chroot 中的 Inkscape 无法在 Android 上启动的原因。

标签: c linux memory-management gcc mmap


【解决方案1】:

是的,更何况这些页面只有在您第一次触摸时才会存在。

顺便说一句,您可以在这种情况下使用标志MAP_ANONYMOUS,无需在/dev/null 上打开文件描述符。

【讨论】:

  • @MetallicPriest 什么都没有。任何未初始化的非文件支持的内存,可能会泄露其他进程或内核内存的内容。
  • 如果您不希望空格填充零,请使用 /dev/urandom 而不是 /dev/zero? :) 内核无法为您提供可能包含在同一内存中运行的其他程序的剩余部分的内存 - 这是一个安全风险。
  • @MetallicPriest,本质上内核没有开销来创建一整页的零。这不是memset 或类似的东西,但通常效率更高。
  • '内核创建一整页的零。这不是 memset' - 你确定吗?创建一个可读的零页 - 是的,没有 memset。但是当您尝试写入尚未写入的“零”页时,pagefault 处理程序将调用 memset:clear_page func;调用自:handle_mm_fault->handle_pte_fault->do_anonymous_page->alloc_zeroed_user_highpage_movable->clear_user_highpage->clear_user_page->clear_page
  • @Jonathan Leffler,内核不会将其他人的页面(也就是来自其他进程的页面)提供给任何其他进程。我认为您did 的意思是这个,但是您的声明听起来用户可以使用一些 sysctl/proc 条目来强制执行该选项,如果他/她愿意的话。我个人会使用 -1 而不是匿名 mmap 的任何文件描述符.为什么要使用零源(本质上是/dev/zero),因为我相信匿名“调入”的虚拟页面已经归零。事实上阅读/proc/<pid>/maps,我们看到匿名映射页面已经归零了。
【解决方案2】:

mmap /dev/zero 和 ANONYMOUS 都没有文件支持,内容也归零。 看看下面的链接 http://man7.org/linux/man-pages/man2/mmap.2.html

【讨论】:

    猜你喜欢
    • 2014-08-05
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    相关资源
    最近更新 更多