fbpx
维基百科

内存映射文件

内存映射文件(Memory-mapped file),或称“文件映射”、“映射文件”,是一段虚内存逐字节对应于一个文件或类文件的资源,使得应用程序处理映射部分如同访问主内存

Memory-mapped file」的各地常用別名
中国大陸內存映射文件
港臺記憶體對映檔案

得益

主要用处是增加I/O性能,特别是用于大文件。对于小文件,内存映射文件会导致碎片空间浪费,[1]因为内存映射总是要对齐页边界,最少耗費4 KiB。故一个5 KiB的文件将会映射占用8 KiB内存,浪费了3 KiB内存。访问内存映射文件比直接文件读写要快几个数量级。

内存映射文件可以只加载一部分内容到用户的逻辑内存空间。这对非常大的文件特别有用。

使用内存映射文件可以避免颠簸英语thrashing (computer science):把相当大的文件直接加载到内存时,由于可用内存不足,使得一边读取文件内存,同时把部分已经加载的文件从内存写入硬盘虚存文件中。

内存映射文件由操作系统的内存管理程序负责,因此绕过了硬盘虚存的分页文件(page file)。[2]

分类

有两类内存映射文件:

Persisted

Persisted文件与硬盘文件相关联,当关闭内存映射时,数据被写入对应的硬盘文件中。适合于很大的文件。[3]

Non-persisted

Non-persisted文件并不关联于硬盘文件。当关闭内存映射文件,所有数据被抛弃。适用于创建进程间通信共享内存[3]

对于Windows操作系统,不需要调用CreateFile。调用CreateFileMapping时,将INVALID_HANDLE_VALUE作为hFile参数传入,指示创建的文件映射对象不是磁盘上的文件,而是页交换文件。所需分配的存储器大小由CreateFileMapping的dwMaximumSizeHigh和dwMaxinumSizeLow参数决定。

缺点

内存映射文件需要在进程的占用一块很大的连续逻辑地址空间。对于Intel的IA-32的4 GiB逻辑地址空间,可用的连续地址空间远远小于2---3 GiB。

相关联的文件的I/O错误(如可拔出驱动器或光驱被弹出,磁盘满时写操作等)的内存映射文件会向应用程序报告SIGSEGV/SIGBUS信号(POSIX环境)或EXECUTE_IN_PAGE_ERROR结构化异常(Windows环境)。通常的内存操作是无需考虑这些异常的。

有内存管理单元(MMU)才支持内存映射文件。

用途

最常见用途是绝大多数操作系统(包括Microsoft WindowsUnix-like系统)用于加载进程[4]

另一个用途是多个进程的共享内存。

第三个用途是对大文件的读写。

支持的平台

一些可移植的库实现:

Java语言FileChannel.

D语言的标准库(std.mmfile module)[9]

Ruby语言的gem(库)Mmap.

Python语言mmap标准库模块.[10]

PerlSys::Mmap[11]File::Map.[12]

Microsoft .NET的P/Invoke,或者Managed access(参见 Memory-Mapped Files (页面存档备份,存于互联网档案馆)). 或第三方库API.[13]

PHP的库函数file_get_contents()( revision log (页面存档备份,存于互联网档案馆)).

R语言的一个库bigmemory (页面存档备份,存于互联网档案馆)使用了Boost库的实现.

J语言至少自从2005年开始支持内存映射文件。它包括了对盒装的阵列数据和单一数据类型文件的支持。支持可以从'data/jmf'加载。J的Jdb和JD数据库引擎使用内存映射文件用于列存储。

类Unix

POSIX函数mmap英语mmap()[14],创建一个内存映射文件,需要提供文件描述符、开始位置的文件指针、映射长度等参数[15]。 or OpenVMS

Windows

Windows API提供了一组函数以实现内存映射文件[16]

  • 创建或打开文件内核对象HANDLE CreateFile(PCSTR pszFileName,DWORD dwDesiredAccess,DWORD dwShareMode,PSECURITY_ATTRIBUTES psa,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile); 要实现内存文件的修改实时转换为磁盘文件的修改,对文件CreateFile时必须写权限。Windows加载PE文件时,会保证写时复制机制的使用。写时复制机制指的是同一个可执行文件的多个进程时,当其中一个进程要改写其映射文件的数据时,Windows会开辟一个新的页文件把要修改页的内容复制到该新页文件中并将新的页文件与当前进程相关联。
    • dwDesiredAccess的值
      • 0:不能读取或写入文件的内容。用于仅需要获得文件的属性时
      • GENERIC_READ:可以从文件中读取数据
      • GENERIC_WRITE:可以将数据写入文件
      • GENERIC_READ|GENERIC_WRITE:可以从文件中读取数据,也可以将数据写入文件
    • dwShareMode的值
      • 0:打开文件的任何尝试均将失败
      • FILE_SHARE_READ:使用GENERIC_WRITE打开文件的其他尝试将会失败
      • FILE_SHARE_WRITE:使用GENERIC_READ打开文件的其他尝试将会失败
      • FILE_SHARE_READ|FILE_SHARE_WRITE:打开文件的其他尝试将会取得成功
  • 创建(或打开)一个文件映射内核对象HANDLE CreateFileMapping(HANDLE hFile,PSECURITY_ATTRIBUTES psa,DWORD fdwProtect,DWORD dwMaximumSizeHigh,DWORD dwMaximumSizeLow,PCTSTR pszName);
    • 第一个参数hFile标识想要映射到进程地址空间中的文件句柄。该句柄由前面调用的CreateFile函数返回。
    • 第二个参数psa参数指向文件映射内核对象的SECURITY_ATTRIBUTES结构的指针,通常传递的值是NULL(它提供默认的安全特性,返回的句柄是不能继承的)。
    • 第三个参数fdwProtect设定保护属性:
      • PAGE_READONLY:当文件映射对象被映射时,可以读取文件的数据。必须已经将GENERIC_READ传递给CreateFile函数
      • PAGE_READWRITE:当文件映射对象被映射时,可以读取和写入文件的数据。必须已经将GENERIC_READ | GENERIC_WRITE传递给CreateFile
      • PAGE_WRITECOPY:当文件映射对象被映射时,可以读取和写入文件的数据。如果写入数据,会导致页面的私有拷贝得以创建。必须已经将GENERIC_READ或GENERIC_WRITE传递给CreateFile
      • SEC_NOCACHE:节保护属性,告诉系统没有将文件的任何内存映射页面放入高速缓存
      • SEC_IMAGE:节保护属性,映射的文件是个PE文件映像。系统确定PE文件各节的保护属性赋予文件映像的各个页面。例如, PE文件的代码节(.text)通常用PAGE_EXECUTE_READ属性, 而PE文件的数据节(.data)通常用PAGE_READWRITE属性。
      • SEC_RESERVE:节保护属性
      • SEC_COMMIT:节保护属性
    • 第四和五个参数dwMaximumSizeHigh和dwMaximumSizeLow:该文件的最大字节数
    • 第六个参数pszName:以0结尾的字符串,给该文件映射对象赋予一个名字。该名字用于与其他进程共享文件映射对象。
  • 文件数据映射到进程地址空间并提交PVOID MapViewOfFile(HANDLE hFileMappingObject,DWORD dwDesiredAccess,DWORD dwFileOffsetHigh,DWORD dwFileOffsetLow,SIZE_T dwNumberOfBytesToMap);
    • 第一个参数hFileMappingObject标识文件映射对象的句柄,该句柄是前面调用CreateFileMapping或OpenFileMapping函数返回的。
    • 第二个参数dwDesiredAccess标识如何访问该数据:
      • FILE_MAP_WRITE:可以读取和写入文件数据。CreateFileMapping函数必须通过传递PAGE_READWRITE标志来调用
      • FILE_MAP_READ:可以读取文件数据。CreateFileMapping函数可以通过传递下列任何一个保护属性来调用:PAGE_READONLY、PAGE_ READWRITE或PAGE_WRITECOPY
      • FILE_MAP_ALL_ACCESS:与FILE_MAP_WRITE相同
      • FILE_MAP_COPY:可以读取和写入文件数据。如果写入文件数据,可以创建一个页面的私有拷贝。CreateFileMapping函数可以用PAGE_READONLY、PAGE_READWRITE或PAGE_WRITECOPY等保护属性中的任何一个来调用。
      • 第三、四个参数dwFileOfsetHigh和dwFileOfsetLow:指定从哪个字节开始作为视图中的第一个字节来映射。
      • 第五个参数dwNumberOfBytesToMap指出多少字节要映射到地址空间。如果设定的值是0,那么系统将设法把从文件中的指定位移开始到整个文件的结尾的视图映射到地址空间。
  • 从进程地址空间撤消文件映射BOOL UnmapViewOfFile(PVOID pvBaseAddress);
    • 参数pvBaseAddress由MapViewOfFile函数返回。
  • 强制系统将修改过的数据重新写入磁盘BOOL FlushViewOfFile(PVOID pvAddress,SIZE_T dwNumberOfBytesToFlush);
    • 第一个参数是内存映射文件视图的一个字节的地址。
    • 第二个参数指明要刷新的字节数。
  • 关闭文件映射对象:用CloseHandle函数
  • 文件对象:用CloseHandle函数

参见

参考文献

  1. ^ . [2017-03-28]. (原始内容存档于2011-08-07). 
  2. ^ , "What Do Memory-Mapped Files Have to Offer?".. [2017-03-28]. (原始内容于2019-01-08). 
  3. ^ 3.0 3.1 Memory-Mapped Files. Microsoft Developer Network. [4 January 2016]. (原始内容于2017-03-04). 
  4. ^ "Demand Paging". [2017-03-28]. (原始内容于2016-03-06). 
  5. ^ Sharing memory between processes: Memory Mapped Files. Boost.org. 
  6. ^ Memory-Mapped Files. Boost.org. 
  7. ^ Memory Mapped Files for Windows and POSIX systems. SourceForge. [2017-03-28]. (原始内容于2016-03-12). 
  8. ^ cpp-mmf. GitHub. [2017-03-28]. (原始内容于2020-11-25). 
  9. ^ std.mmfile - D Programming Language. Digital Mars. [4 December 2011]. (原始内容于2020-10-03). 
  10. ^ . [23 December 2008]. (原始内容存档于2006年12月30日). 
  11. ^ Sys::Mmap Perl Module. 
  12. ^ File::Map Perl Module. [2017-03-28]. (原始内容于2013-06-13). 
  13. ^ DotNet. [2017-03-28]. (原始内容于2010-04-19). 
  14. ^ Memory Mapped Files. [2017-03-28]. (原始内容于2007-02-09). 
  15. ^ Apple - Mac OS X Leopard - Technology - UNIX. [2017-03-28]. (原始内容于2009-04-23). 
  16. ^ CreateFileMapping Function (Windows). [2017-03-28]. (原始内容于2008-10-10). 

内存映射文件, memory, mapped, file, 或称, 文件映射, 映射文件, 是一段虚内存逐字节对应于一个文件或类文件的资源, 使得应用程序处理映射部分如同访问主内存, memory, mapped, file, 的各地常用別名中国大陸內存映射文件港臺記憶體對映檔案目录, 得益, 分类, persisted, persisted, 缺点, 用途, 支持的平台, 类unix, windows, 参见, 参考文献得益, 编辑主要用处是增加i, o性能, 特别是用于大文件, 对于小文件, 会导致碎片空间浪费. 内存映射文件 Memory mapped file 或称 文件映射 映射文件 是一段虚内存逐字节对应于一个文件或类文件的资源 使得应用程序处理映射部分如同访问主内存 Memory mapped file 的各地常用別名中国大陸內存映射文件港臺記憶體對映檔案目录 1 得益 2 分类 2 1 Persisted 2 2 Non persisted 3 缺点 4 用途 5 支持的平台 5 1 类Unix 5 2 Windows 6 参见 7 参考文献得益 编辑主要用处是增加I O性能 特别是用于大文件 对于小文件 内存映射文件会导致碎片空间浪费 1 因为内存映射总是要对齐页边界 最少耗費4 KiB 故一个5 KiB的文件将会映射占用8 KiB内存 浪费了3 KiB内存 访问内存映射文件比直接文件读写要快几个数量级 内存映射文件可以只加载一部分内容到用户的逻辑内存空间 这对非常大的文件特别有用 使用内存映射文件可以避免颠簸 英语 thrashing computer science 把相当大的文件直接加载到内存时 由于可用内存不足 使得一边读取文件内存 同时把部分已经加载的文件从内存写入硬盘虚存文件中 内存映射文件由操作系统的内存管理程序负责 因此绕过了硬盘虚存的分页文件 page file 2 分类 编辑有两类内存映射文件 Persisted 编辑 Persisted文件与硬盘文件相关联 当关闭内存映射时 数据被写入对应的硬盘文件中 适合于很大的文件 3 Non persisted 编辑 Non persisted文件并不关联于硬盘文件 当关闭内存映射文件 所有数据被抛弃 适用于创建进程间通信的共享内存 3 对于Windows操作系统 不需要调用CreateFile 调用CreateFileMapping时 将INVALID HANDLE VALUE作为hFile参数传入 指示创建的文件映射对象不是磁盘上的文件 而是页交换文件 所需分配的存储器大小由CreateFileMapping的dwMaximumSizeHigh和dwMaxinumSizeLow参数决定 缺点 编辑内存映射文件需要在进程的占用一块很大的连续逻辑地址空间 对于Intel的IA 32的4 GiB逻辑地址空间 可用的连续地址空间远远小于2 3 GiB 相关联的文件的I O错误 如可拔出驱动器或光驱被弹出 磁盘满时写操作等 的内存映射文件会向应用程序报告SIGSEGV SIGBUS信号 POSIX环境 或EXECUTE IN PAGE ERROR结构化异常 Windows环境 通常的内存操作是无需考虑这些异常的 有内存管理单元 MMU 才支持内存映射文件 用途 编辑最常见用途是绝大多数操作系统 包括Microsoft Windows与Unix like系统 用于加载进程 4 另一个用途是多个进程的共享内存 第三个用途是对大文件的读写 支持的平台 编辑一些可移植的库实现 Boost Interprocess 5 在Boost C Libraries Boost Iostreams 6 也在Boost C Libraries Fmstream 7 Cpp mmf 8 Java语言的FileChannel D语言的标准库 std mmfile module 9 Ruby语言的gem 库 Mmap Python语言的mmap标准库模块 10 Perl的Sys Mmap 11 或File Map 12 Microsoft NET的P Invoke 或者Managed access 参见 Memory Mapped Files 页面存档备份 存于互联网档案馆 或第三方库API 13 PHP的库函数file get contents revision log 页面存档备份 存于互联网档案馆 R语言的一个库bigmemory 页面存档备份 存于互联网档案馆 使用了Boost库的实现 J语言至少自从2005年开始支持内存映射文件 它包括了对盒装的阵列数据和单一数据类型文件的支持 支持可以从 data jmf 加载 J的Jdb和JD数据库引擎使用内存映射文件用于列存储 类Unix 编辑 POSIX函数mmap 英语 mmap 14 创建一个内存映射文件 需要提供文件描述符 开始位置的文件指针 映射长度等参数 15 or OpenVMS Windows 编辑 Windows API提供了一组函数以实现内存映射文件 16 创建或打开文件内核对象HANDLE CreateFile PCSTR pszFileName DWORD dwDesiredAccess DWORD dwShareMode PSECURITY ATTRIBUTES psa DWORD dwCreationDisposition DWORD dwFlagsAndAttributes HANDLE hTemplateFile 要实现内存文件的修改实时转换为磁盘文件的修改 对文件CreateFile时必须写权限 Windows加载PE文件时 会保证写时复制机制的使用 写时复制机制指的是同一个可执行文件的多个进程时 当其中一个进程要改写其映射文件的数据时 Windows会开辟一个新的页文件把要修改页的内容复制到该新页文件中并将新的页文件与当前进程相关联 dwDesiredAccess的值 0 不能读取或写入文件的内容 用于仅需要获得文件的属性时 GENERIC READ 可以从文件中读取数据 GENERIC WRITE 可以将数据写入文件 GENERIC READ GENERIC WRITE 可以从文件中读取数据 也可以将数据写入文件 dwShareMode的值 0 打开文件的任何尝试均将失败 FILE SHARE READ 使用GENERIC WRITE打开文件的其他尝试将会失败 FILE SHARE WRITE 使用GENERIC READ打开文件的其他尝试将会失败 FILE SHARE READ FILE SHARE WRITE 打开文件的其他尝试将会取得成功 创建 或打开 一个文件映射内核对象HANDLE CreateFileMapping HANDLE hFile PSECURITY ATTRIBUTES psa DWORD fdwProtect DWORD dwMaximumSizeHigh DWORD dwMaximumSizeLow PCTSTR pszName 第一个参数hFile标识想要映射到进程地址空间中的文件句柄 该句柄由前面调用的CreateFile函数返回 第二个参数psa参数指向文件映射内核对象的SECURITY ATTRIBUTES结构的指针 通常传递的值是NULL 它提供默认的安全特性 返回的句柄是不能继承的 第三个参数fdwProtect设定保护属性 PAGE READONLY 当文件映射对象被映射时 可以读取文件的数据 必须已经将GENERIC READ传递给CreateFile函数 PAGE READWRITE 当文件映射对象被映射时 可以读取和写入文件的数据 必须已经将GENERIC READ GENERIC WRITE传递给CreateFile PAGE WRITECOPY 当文件映射对象被映射时 可以读取和写入文件的数据 如果写入数据 会导致页面的私有拷贝得以创建 必须已经将GENERIC READ或GENERIC WRITE传递给CreateFile SEC NOCACHE 节保护属性 告诉系统没有将文件的任何内存映射页面放入高速缓存 SEC IMAGE 节保护属性 映射的文件是个PE文件映像 系统确定PE文件各节的保护属性赋予文件映像的各个页面 例如 PE文件的代码节 text 通常用PAGE EXECUTE READ属性 而PE文件的数据节 data 通常用PAGE READWRITE属性 SEC RESERVE 节保护属性 SEC COMMIT 节保护属性 第四和五个参数dwMaximumSizeHigh和dwMaximumSizeLow 该文件的最大字节数 第六个参数pszName 以0结尾的字符串 给该文件映射对象赋予一个名字 该名字用于与其他进程共享文件映射对象 文件数据映射到进程地址空间并提交PVOID MapViewOfFile HANDLE hFileMappingObject DWORD dwDesiredAccess DWORD dwFileOffsetHigh DWORD dwFileOffsetLow SIZE T dwNumberOfBytesToMap 第一个参数hFileMappingObject标识文件映射对象的句柄 该句柄是前面调用CreateFileMapping或OpenFileMapping函数返回的 第二个参数dwDesiredAccess标识如何访问该数据 FILE MAP WRITE 可以读取和写入文件数据 CreateFileMapping函数必须通过传递PAGE READWRITE标志来调用 FILE MAP READ 可以读取文件数据 CreateFileMapping函数可以通过传递下列任何一个保护属性来调用 PAGE READONLY PAGE READWRITE或PAGE WRITECOPY FILE MAP ALL ACCESS 与FILE MAP WRITE相同 FILE MAP COPY 可以读取和写入文件数据 如果写入文件数据 可以创建一个页面的私有拷贝 CreateFileMapping函数可以用PAGE READONLY PAGE READWRITE或PAGE WRITECOPY等保护属性中的任何一个来调用 第三 四个参数dwFileOfsetHigh和dwFileOfsetLow 指定从哪个字节开始作为视图中的第一个字节来映射 第五个参数dwNumberOfBytesToMap指出多少字节要映射到地址空间 如果设定的值是0 那么系统将设法把从文件中的指定位移开始到整个文件的结尾的视图映射到地址空间 从进程地址空间撤消文件映射BOOL UnmapViewOfFile PVOID pvBaseAddress 参数pvBaseAddress由MapViewOfFile函数返回 强制系统将修改过的数据重新写入磁盘BOOL FlushViewOfFile PVOID pvAddress SIZE T dwNumberOfBytesToFlush 第一个参数是内存映射文件视图的一个字节的地址 第二个参数指明要刷新的字节数 关闭文件映射对象 用CloseHandle函数 文件对象 用CloseHandle函数参见 编辑存储器映射输入输出参考文献 编辑 存档副本 2017 03 28 原始内容存档于2011 08 07 What Do Memory Mapped Files Have to Offer 2017 03 28 原始内容存档于2019 01 08 3 0 3 1 Memory Mapped Files Microsoft Developer Network 4 January 2016 原始内容存档于2017 03 04 Demand Paging 2017 03 28 原始内容存档于2016 03 06 Sharing memory between processes Memory Mapped Files Boost org Memory Mapped Files Boost org Memory Mapped Files for Windows and POSIX systems SourceForge 2017 03 28 原始内容存档于2016 03 12 cpp mmf GitHub 2017 03 28 原始内容存档于2020 11 25 std mmfile D Programming Language Digital Mars 4 December 2011 原始内容存档于2020 10 03 New Modules in 1 6 23 December 2008 原始内容存档于2006年12月30日 Sys Mmap Perl Module File Map Perl Module 2017 03 28 原始内容存档于2013 06 13 DotNet 2017 03 28 原始内容存档于2010 04 19 Memory Mapped Files 2017 03 28 原始内容存档于2007 02 09 Apple Mac OS X Leopard Technology UNIX 2017 03 28 原始内容存档于2009 04 23 CreateFileMapping Function Windows 2017 03 28 原始内容存档于2008 10 10 取自 https zh wikipedia org w index php title 内存映射文件 amp oldid 75707250, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。