[笔记]Windows核心编程《十七》内存映射文件

网友投稿 1186 2022-09-16

[笔记]Windows核心编程《十七》内存映射文件

[笔记]Windows核心编程《十七》内存映射文件

​​参考​​

文章目录

​​前言​​​​一、映射到内存的可执行文件和DLL​​

​​CreateProcess调用过程​​​​通过LoadLibrary从exe和dll的段地址 读取DLL列表​​

​​二、映射到内存的数据文件​​​​三、使用内存映射文件​​​​四、用内存映射文件来处理大文件​​​​五、内存映射文件和一致性​​​​六、给内存映射文件的指定基地址​​​​七、内存映射文件的实现细节​​​​八、用内存映射文件再进程间共享数据​​​​九、以页交换文件为后背存储器的内存映射文件​​​​十、 稀疏调拨的内存映射文件​​​​总结​​

​​1.程序启动过程?加载dll错误处理?​​

前言

内存映射文件 与虚拟内存相似,内存映射文件允许开发人员预定一块地址空间区域并给区域调拨物理存储器。​不同之处在于内存映射文件的物理存储器来自磁盘上已有的文件,而不 是来自系统的页交换文件。​ 一旦把文件映射到地址空间,我们就可以对它进行访问,就好像整个文件都已经在被载入内存一样。

页交换文件,简单讲就是系统用于做虚拟内存的一个磁盘文件​​页交换文件相关可参考windows内存体系结构​​

内存映射主要用于以下三种情况:

系统使用内存映射文件来载入并运行.exe和动态链接库(DLL)。这大量节省了页交换文件的空间以及应用程序启动的时间。开发人员可以使用内存映射文件来访问磁盘上的数据文件。这使得我们可以避免直接对文件进行I/O操作和对文件内容进行缓存。通过使用内存映射文件,我们可以在同一台机器的不同进程间共享数据。Windows的确提供了其它一些方法来在进程间传送数据,但这些方法都是通过内存映射文件来实现的。因此,如果在同一台机器的不同进程之间共享数据,内存映射文件时最高效的方法。

一、映射到内存的可执行文件和DLL

CreateProcess调用过程

当一个线程在调用CreateProcess的时候,系统会执行以下步骤:

系统会先确定CreateProcess所指定的可执行文件所在的位置。如果无法找到该.exe文件,那么系统将不会创建进程,这时CreateProcess会返回FALSE.系统创建一个新的进程内核对象。系统为新进程创建一个私有地址空间。系统预定一块足够大的地址空间来容纳.exe。待预定的地址空间区域的具体位置已经在.exe文件中指定。 默认情况下,.exe文件的基地址是0x00400000。但是,只需在构建应用程序的.exe文件时使用/BASE连接器开关,我们就可以给自己的应用程序指定一个不同的地址。系统会对地址空间区域进行标注,表明该区域的后备物理存储器来自磁盘上的.exe文件,而并非来自系统的页交换文件。

通过LoadLibrary从exe和dll的段地址 读取DLL列表

当系统把.exe文件映射到进程的地址空间之后,会访问.exe文件中一个段,这个段列出了一些DLL文件,它们包含该.exe文件调用到的函数。然后系统会调用LoadLibrary来载入每个DLL,如果哪个DLL需要用到其它DLL,那么系统同样会调用其它DLL,那么系统同样会调用 LoadLibrary来载入相应的DLL。

每当调用LoadLibrary来加载一个DLL时,系统将执行下列操作步骤,它们均类似上面的第4和第5个步骤:

系统会预定一块足够大的地址空间区域来容纳DLL文件。待预定的的地址空间区域的具体位置已经在DLL文件中指定。按照默认设置, Microsoft的Visual C++建立的 D L L文件基地址是0 x10000000(这个地址可能不同于在 64位Windows 2000上运行的6 4位D L L的地址)但是,你可以在创建DLL文件时重载这个地址,方法是使用链接程序的 /BASE选项。所有与Windows一起发布的系统DLL都有不同的基地址,这样即使把它们载入到同一个地址空间,也不会发生重叠。如果系统无法在DLL文件指定的基地址处预定区域,这可能是因为该区域已经被另一个DLL或.exe占用,也可能是区域不够大,这时系统会尝试在另一个地址 来为DLL预定地址空间区域。如果DLL不包含重定位信息(当使用连接器的/FIXED开关来构建DLL),这意味着DLL必须被载入到指定的基地址,否则无法被载入。如果对DLL执行重定位,重定位不仅需要占用页交换文件中额外的存储空间,而且会增加载入DLL所需的时间。系统会对地址空间区域进行标注,表明该区域的后备物理存储器来自磁盘上的DLL文件,而并非来自页交换文件。如果由于Windows不能将DLL载入到指定的基地址而必须重定位的话,那么系统还会另外进行标注,表明DLL中有一部分物理存储器映射到了页交换文件。

注意:如果由于某个原因系统无法映射 . e x e和所有必要的D L L文件,那么系统就会向用户​显示一个消息框​,并且释放进程的地址空间和进程对象。CreateProcess函数将向调用者返回 FALSE,调用者可以调用GetLastError函数,以便更好地了解为什么无法创建该进程。

把所有的.exe文件和DLL文件都映射到进程的地址空间之后,系统会开始执行.exe文件的启动代码。当完成对.exe文件的映射后,系统会负责所有的换页(paging)、缓存(buffering)、以及高速缓存(caching)操作。

例如, 如果.exe文件中的代码使它​跳到一个尚未加载到内存的指令地址,那么就会出现一个错误​。 系统能够发现这个错误,并且自动将这页代码从该文件的映像加载到一个 RAM页面。 然后,系统将这个RAM页面映射到进程的地址空间中的相应位置,并且让线程继续运行,就像这页代码已经加载了一样。 当然,这一切是应用程序看不见的。当进程中的线程每次试图访问尚未加载到RAM的代码或数据时,该进程就会重复执行

二、映射到内存的数据文件

三、使用内存映射文件

四、用内存映射文件来处理大文件

五、内存映射文件和一致性

六、给内存映射文件的指定基地址

七、内存映射文件的实现细节

八、用内存映射文件再进程间共享数据

九、以页交换文件为后背存储器的内存映射文件

十、 稀疏调拨的内存映射文件

总结

1.程序启动过程?加载dll错误处理?

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Windows 通过编辑注册表设置左右手使用习惯更改 Popup 弹出位置
下一篇:[云原生专题-16]:容器 - 在Windows主机上搭建Docker环境
相关文章

 发表评论

暂时没有评论,来抢沙发吧~