mmap如何工作?

Sha*_*ang 9 linux memory malloc mmap

我正在研究Linux中需要来自硬盘的mmap文件的程序,但我有一个问题,是什么能使它失败.就像所有的内存都碎片化,每个只有200M,但我想将文件mmap到1000M的内存,它会成功吗?

还有一个问题,Linux中是否有任何工具可以像Windows中的某些工具一样重新收集内存,例如xp的内置工具.

谢谢.

Wyz*_*a-- 19

mmap() 使用地址outide你的程序的堆区域,所以堆碎片是没有问题的,但在某种程度上,它可以使堆占用更多的空间,并减少映射的可用空间.

如果您有大量映射文件,则可能会遇到地址空间相对受限的32位系统碎片问题.在64位系统上,碎片不太可能成为问题,因为即使现有映射之间只有小区域可用,仍然有许多可用的连续地址空间,与现有映射相邻.

32位系统上更常见的问题是地址空间太小而根本无法映射大文件.在4GB地址空间中,通常2GB可供用户空间使用,另外2GB由内核保留.在可用的2GB中,您的映射必须与程序的代码和堆栈(通常很小)和堆(可能很大)共享空间.

简而言之,mmap()如果文件太大,通常会在32位系统上失败,但是你不可能有足够大的文件在64位系统上造成这个问题.

如果您正在创建私有的写时复制映射,则由于缺少交换空间,它也可能会失败.内核必须确保可用RAM和交换的总和足够大,以保持映射的大小,以防您修改所有页面,以便内核被强制创建所有页面的私有副本.共享映射不应该有这个问题,因为可以将更改刷新到磁盘上的文件,然后如果内存不足并且稍后从磁盘重新加载,则可以丢弃页面.

当然,如果您没有访问该文件的权限,或者它不是可以映射的文件类型(例如目录或套接字),映射也会失败.

目前还不清楚你对回忆记忆的意思.请记住,mmap()消耗的稀缺资源不是内存,而是地址空间.您可以潜在地映射即使机器却只有128MB的RAM 1GB的文件,但在32位系统上,即使机器有16GB的RAM,不能映射4GB的文件.

虚拟内存的概念对于理解什么是必不可少的mmap(),所以如果您已经不熟悉它,请阅读相关内容.


asv*_*kau 12

mmap通过操作进程的页表来工作,页表是 CPU 用来映射地址空间的数据结构。CPU 会将“虚拟”地址转换为“物理”地址,并根据内核设置的页表执行此操作。

当您第一次访问映射内存时,您的 CPU 会产生一个页面错误。然后操作系统内核可以跳入,通过在新分配的缓冲区中分配内存和执行文件 I/O 来“修复”无效的内存访问,然后继续执行程序,就好像什么也没发生一样。

mmap如果您的进程地址空间不足,则可能会失败,这些天对于 32 位代码需要注意,在这些代码中,所有可用地址都可以通过大型数据集快速映射。对于联机帮助页的“错误”部分中提到的任何事情,它也可能失败。

如果内核在分配内存或执行 I/O 时出现问题,访问映射区域内的内存也会失败。在这种情况下,您的进程将收到一个SIGBUS 信号