页交换文件与内存映射文件
内存的几种状态和类型
私有类型:
使用VitualAlloc申请分配/调拨内存后,申请的内存只能被当前进程使用。其他进程无法访问。这就是所谓的私有内存
映射类型 -> 页交换文件(虚拟内存)
页交换文件补充了我们的物理内存的不足。在内存中长时间不活跃的数据,系统会将内存写入页交换文件。用以节省内存,所以页交换文件也是计算机内存的一部分
在开启了相应功能后,页交换文件就静静的躺在 c盘根目录,名字为pagefile.sys
映射类型 mapping:
页交互文件除了可以应急存储不活跃数据以外,还可以开辟空间作为内存映射空间
可以用来作为进程间共享的内存,实现进程间通讯。(以内存形式可以被映射到多个进程)
映象类型 image:
操作系统在加载可执行文件(exe)和模块(dll)的时候,为了快速启动和节省内存,操作系统使用了映象。将文件映射到进程虚拟内存空间中。与映射(mapping)内存的从页交换文件中映射到内存中不同,映象直接把源文件从磁盘中映射到进程虚拟内存空间中(相当于临时页交换文件)。
因为会映射到多个进程,为了防止被随意改的安全。在挂载磁盘文件到进程虚拟内存空间之前,会在系统的页交换文件中申请相同大小的空间,但是不拷贝数据,并且加上PAGE_WRITECOPY
写拷贝属性,此时再去挂载到进程虚拟内存空间。
当进程在进程内部改写dll的数据的时候,也就是写那块被标记为写拷贝属性内存的时候。此时会把要改的数据拷贝到页交互文件中,与此同时。内存的映射指针也从文件指向了页交换文件。也就是此时其实改的是页交换文件而不是源文件了。这样一来不同进程就可以公用exe文件并且可以随意修改而不会相互影响了
映射类型 - 创建共享内存
//创建文件映射对象
HANDLE CreateFileMapping(
HANDLE hFile, // 文件句柄,如果是真实文件则需要填写,共享内存需要填写宏 INVALID_HANDLE_VALUE
LPSECURITY_ATTRIBUTES lpAttributes, // 安全描述
DWORD flProtect, // 页面保护属性
DWORD dwMaximumSizeHigh, // 文件映射对象的最大大小的高位DWORD (null)
DWORD dwMaximumSizeLow, // 文件映射对象的最大大小的低位DWORD (大小)
LPCTSTR lpName // 名字指针
);
//映射到虚拟地址空间 将文件映射的视图映射到调用进程的地址空间中。
LPVOID MapViewOfFile(
HANDLE hFileMappingObject, // 一个文件映射对象的句柄。CreateFileMapping和 OpenFileMapping函数返回该句柄。
DWORD dwDesiredAccess, // 文件映射对象的访问类型,它决定页面的保护
DWORD dwFileOffsetHigh, // 文件偏移量的高位DWORD。
DWORD dwFileOffsetLow, // 始位置的文件偏移量的低位DWORD
SIZE_T dwNumberOfBytesToMap // 映射到视图的文件映射的字节数
);
//MapViewOfFile 设置的权限指的是 进程使用进程的内存虚拟空间中所生效的权限
//CreateFileMapping 设置的权限是 页交换文件中映射的内存的访问权限
//在同一个 handel中 MapViewOfFile 的权限必须小于或等于INVALID_HANDLE_VALUE所声明的权限