汇编中内存映射文件的概念 and 内存映射文件的实现原理

来源:互联网 发布:新闻出版网络教育系统 编辑:程序博客网 时间:2024/06/06 19:17

Org: http://hi.baidu.com/whyyit/blog/item/80616312c977a655f819b8e3.html

内存映射文件提供了一组独立的函数,使应用程序能够通过内存指针像访问内存一样对磁盘上的文件进行访问。通过内存映射文件函数可以将磁盘上文件的全部和部分映射到进程虚拟地址空间的某个位置,一旦完成了映射,对文件内容的访问就如同在该地址区域内直接对内存访问一样简单。这样,向文件中写入数据的操作就是直接对内存进行赋值,而从文件的某个特定位置读取数据也就是直接从内存中取数据。


当内存映射文件提供了对文件某个特定位置的直接读写时,真正对磁盘文件的读写操作是由系统底层处理的。而且在写操作时,数据也并非在每次操作时都即时写入到磁盘,而是通过缓冲处理来提高系统的整体性能。

使用内存映射文件的一个好处是系统对所有的数据传输都是通过4 KB大小的数据页面来实现的,这意味着一些小的文件操作将被缓冲入一次大的操作之中,也就是说首次存取文件中某段数据的时候,会引发一次磁盘操作并将数据所在的一个页面全部读入,到以后对附近的数据进行操作时,所需的数据已经被前一次的页面操作读入到内存,无需再进行一次磁盘操作,从而提高了系统的性能。

使用内存映射文件的另一个好处是程序代码以标准的内存地址形式来访问文件数据,按页面大小周期性从磁盘读入数据的操作发生在后台,由操作系统底层来实现,这个过程对应用程序是完全透明的。虽然用内存映射文件最终还是要将文件从磁盘读入内存,实质上并没有省略掉什么操作,整体性能可能并没有获得什么提高,但是程序的结构将会从中受益,缓冲区边界等问题将不复存在。而且,对文件内容更新后的写入操作也由操作系统自动完成,操作系统判断内存中的页面是否为脏页面并仅将脏页面写入磁盘,比程序自己将全部数据写入文件的效率要高了很多。

2. 内存映射文件的实现原理

Windows使用的是页式虚拟存储管理,在Windows中,地址空间中的每个页面在任一给定时刻都可以是三种状态之一:空闲的、保留的或者是已经提交物理内存的。这些页面根据需要由操作系统交换进内存或换出内存。当内存中的某个页面不再需要时,操作系统将取消原来拥用该页面的应用程序对它的控制权,并释放该页面以供其他应用程序使用;当该页面再次成为需求页面时,它将被从物理存储器中重新读入内存,物理存储器既可以是物理内存,也可以是磁盘上的页文件。

内存映射文件的实现基于同样的原理,内存映射文件是Windows内部已有的内存管理组件的一个扩充,与实现虚拟内存一样,内存映射文件保留了一个地址空间的区域,并根据需要将物理存储器提交给该区域。它们之间的区别在于,当内存映射文件用来存取一个磁盘文件的时候,它提交的物理存储器就来自于这个文件。

不仅应用程序使用内存映射文件来访问磁盘上的数据文件,Windows操作系统同样使用内存映射文件加载和执行exe和dll文件,这样可以大大节省页文件空间和应用程序启动运行所需的时间。如图10.7所示,对于每个进程,系统将可执行的代码页提交到磁盘中的可执行文件中,而数据页(包括进程的静态数据段以及动态分配的内存)则被提交到虚拟内存中。

除了加载文件,使用内存映射文件也可以在同一台计算机上运行的多个进程之间共享数据,而且内存映射文件是多个进程互相进行通信的最有效的方法。那么如何实现数据共享呢,其实原理很简单,如图10.8所示,对于不同进程间共享的数据页,只要将它们提交到虚拟内存的同样页面就可以了,这样,当一个进程改变了数据页的内容时,通过分页映射机制,其他进程的共享数据区的内容就会同时改变,因为它们实际上存储在同一个地方。



图10.7 用内存映射文件加载执行文件

图10.8 用内存映射文件实现进程间共享数据


原创粉丝点击