问题描述
我无法理解 linux 中的内存映射页面和匿名页面.有人可以用一个例子来解释它吗?与它们相关的内核数据结构是什么?
I am not able to understand memory mapped page and anonymous page in linux. Can someone please explain it with an example? What are the kernel data structures related to them?
推荐答案
正确的术语是内存映射文件和匿名映射.当提到内存映射时,通常指的是 mmap(2).使用 mmap 有 2 个类别.一类是共享映射与私有映射.另一个类别是文件与匿名映射.混合在一起,您将获得以下 4 种组合:
The correct terms are memory mapped files and anonymous mappings. When referring to memory mapping, one is usually referring to mmap(2). There are 2 categories for using mmap. One category is SHARED vs PRIVATE mappings. The other category is FILE vs ANONYMOUS mappings. Mixed together you get the 4 following combinations:
- 私人文件映射
- 共享文件映射
- 私人匿名映射
- 共享匿名映射
文件映射指定磁盘上的一个文件,它将有 N 个字节映射到内存中.函数 mmap(2) 将要映射到内存的文件的文件描述符作为其第四个参数.第 5 个参数是要读入的字节数,作为偏移量.使用mmap创建内存映射文件的典型流程是
A File Mapping specifies a file, on disk, that will have N many bytes mapped into memory. The function mmap(2) takes, as its 4th argument a file descriptor to the file to be mapped into memory. The 5th argument is the number of bytes to be read in, as an offset. The typical process of using mmap to create a memory mapped file goes
- open(2) 文件以获取文件描述符.
- fstat(2) 从文件描述符数据结构中获取文件大小.
- mmap(2) 使用从 open(2) 返回的文件描述符来映射文件.
- 关闭(2) 文件描述符.
- 对内存映射文件执行任何操作.
当文件被映射为 PRIVATE 时,所做的更改不会提交到基础文件.它是文件的私有内存副本.当文件被映射为 SHARED 时,内核会自动将所做的更改提交给底层文件.映射为共享的文件可用于所谓的内存映射 I/O 和 IPC.如果您需要文件的持久性,您可以为 IPC 使用内存映射文件而不是共享内存段
When a file is mapped in as PRIVATE, changes made are not committed to the underlying file. It is a PRIVATE, in-memory copy of the file. When a file is mapped SHARED, changes made are committed to the underlying file by the kernel automatically. Files mapped in as shared can be used for what is called Memory Mapped I/O, and IPC. You would use a memory mapped file for IPC instead of a shared memory segment if you need the persistence of the file
如果您使用 strace(1) 观察进程初始化,您会注意到文件的不同部分使用 mmap(2) 作为私有文件映射进行映射.系统库也是如此.
If you use strace(1) to watch a process initialize, you will notice that the different sections of the file are mapped in using mmap(2) as private file mappings. The same is true for system libs.
strace(1) 的输出示例,其中 mmap(2) 用于在库中映射到进程.
Examples of output from strace(1) where mmap(2) is being used to map in libraries to the process.
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=42238, ...}) = 0
mmap(NULL, 42238, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff7ca71e000
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY) = 3
read(3, "177ELF2113 3 >