内核mmap操作的内存大小


9

我对Linux mmap将文件放到主内存中的方式(在我的上下文中为执行,但我想mmap进程在写入和读取方面是相同的)及其使用的大小感兴趣。

因此,我知道Linux使用的页面调度通常为4kB页面大小(我在内核中可以找到这个大小吗?)。但这对分配的内存到底意味着什么:假设您的二进制文件大小只有几千个字节,让我们说5812B,然后执行它。内核中会发生什么:它是否分配2 * 4kB,然后将5812B复制到该空间中,从而在第二页中浪费了大于3KB的主内存?

如果有人知道内核资源中定义了pagesize的文件,那就太好了。

我想第二个问题也非常简单:我以5812B为文件大小。大小是从inode取得的,对吗?

Answers:


6

可执行文件的大小和内存中的大小之间没有直接关系。这是执行二进制文件时的简要概述:

  1. 内核解析该文件并将其分成多个部分。有些部分在单独的页面中直接加载到内存中。某些部分根本没有加载(例如调试符号)。
  2. 如果可执行文件是动态链接的,则内核将调用动态加载程序,并加载所需的共享库并根据需要执行链接版本。
  3. 该程序开始执行其代码,通常它将请求更多的内存来存储数据。

有关可执行文件格式,链接和可执行文件加载的更多信息,您可以阅读John R. Levine的链接器和加载器。

在5kB可执行文件中,除了标头之外,所有内容都可能是需要加载到内存中的代码或数据。可执行代码将至少是一页,也许是两页,然后堆栈将至少有一页,可能至少是一页或堆(其他数据),再加上共享库使用的内存。

在Linux下,您可以使用来检查内存映射以查找可执行文件cat /proc/$pid/maps。该格式记录在proc(5)手册页中。另请参阅了解Linux / proc / id / maps


0

是的:您最终会得到两个4k页面。数据是按需加载的,因此,如果没有任何内容引用第二页,则它将永远不会加载到内存中。

include/asm-i386/param.h:#define EXEC_PAGESIZE  4096
include/asm-i386/elf.h:#define ELF_EXEC_PAGESIZE        4096

不要更改这些值,不要期望任何事情起作用。

是的,文件大小存储在ext2 / 3的索引节点中。


0

对于定义部分,在Intel体系结构的2.6.38〜ish内核上:

arch / x86 / include / asm / page_types.h:

/ * PAGE_SHIFT确定页面大小* /

#定义PAGE_SHIFT 12

#定义PAGE_SIZE(_AC(1,UL)<< PAGE_SHIFT)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.