《2022年内存映射文件测试报告 .pdf》由会员分享,可在线阅读,更多相关《2022年内存映射文件测试报告 .pdf(13页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、内存映射文件测试报告内存映射文件测试报告(windows)名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 13 页 - - - - - - - - - 内存映射文件测试报告目录1 内存映射文件简介. 31.1 内存映射文件概念. 31.2 内存映射文件优点. 31.3 内存映射文件原理简述. 32 内存映射文件函数(windows ) . 42.1 内存映射文件操作流程. 42.2 函数说明 . 42.2.1 CreateFile . 42.2.2 CreateFileM
2、apping . 42.2.3 MappViewOfFile . 53 测试用例及结果(windows ) . 53.1 用例 1 . 53.1.1 测试目的及流程. 53.1.2 测试结果 . 63.2 用例 2 . 63.2.1 测试目的及流程. 63.2.2 测试结果 . 73.3 用例 3 . 73.3.1 测试目的及流程. 73.3.2 测试结果 . 73.4 用例 4 . 73.4.1 测试目的及流程. 73.4.2 测试结果 . 83.5 用例 5 . 83.5.1 测试目的及流程. 83.5.2 测试结果 . 84 其他说明 . 85 附录(代码) . 95.1 创建内存映射文
3、件代码. 95.2 测试用例 3 代码 . 10 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 13 页 - - - - - - - - - 内存映射文件测试报告1 内存映射文件简介1.1 内存映射文件概念内存映射文件提供了一组独立的函数,使应用程序能够通过内存指针像访问内存一样访问磁盘上的文件。 通过内存映射文件函数可以将磁盘上的文件全部或者部分映射到进程的虚拟地址空间的某个位置。一旦完成映射, 对磁盘文件的访问就可以像访问内存文件一样便捷。1.2 内存映射文件优点文
4、件操作是应用程序最为基本的功能之一,Win32 API 和 MFC均提供有支持文件处理的函数和类,常用的有Win32 API 的 CreateFile()、WriteFile()、ReadFile()和 MFC提供的 CFile 类等。一般来说,以上这些函数可以满足大多数场合的要求,但是对于某些特殊应用领域所需要的动辄几十GB、几百 GB、乃至几 TB的海量存储,再以通常的文件处理方法进行处理显然是行不通的。因此提出内存映射文件,它的优点为:(1)系统使用内存映射文件,以便加载和执行.exe 和 DLL文件。这可以大大节省页文件空间和应用程序启动运行所需的时间。(2)可以使用内存映射文件来访问
5、磁盘上的数据文件。可以不必对文件执行I/O 操作,并且可以不必对文件内容进行缓存。(3)可以使用内存映射文件,使同一台计算机上运行的多个进程能够相互之间共享数据。注:使用内存映射文件数据传输是通过4k 大小的数据页面实现的。1.3 内存映射文件原理简述内存映射文件是将硬盘上文件的位置与进程逻辑地址空间中一块大小相同的区域之间的一一对应。 这种对应关系纯属是逻辑上的概念,物理上是不存在的,原因是进程的逻辑地址空间本身就是不存在的。在内存映射的过程中,并没有实际的数据拷贝,文件没有被载入内存,只是逻辑上被放入了内存。内 存 映 射 文 件是 把 数 据文 件 的 一 部 分映 射 到 虚拟 地 址
6、 空 间 (映 射 到 的区 域 是 在0 x8000000000 xBFFFFFFF内),但不提交RAM,存取这段内存的指令同样会产生页面异常。操作系统捕获到这个异常后,分配一页RAM,并把它映射到当前进程发生异常的地址处,然后系统把文件中相应的数据独到这个页面中,继续执行刚才产生异常的指令。它使应用程序可以通过内存指针对磁盘上的文件进行访问,其过程就如同对加载了文件的内存的访问。 通过文件映射这种使磁盘文件的全部或部分内容与进程虚拟地址空间的某个区域建立映射关联的能力,可以直接对被映射的文件进行访问,而不必执行文件I/O 操作也名师资料总结 - - -精品资料欢迎下载 - - - - -
7、- - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 13 页 - - - - - - - - - 内存映射文件测试报告无需对文件内容进行缓冲处理。内存文件映射的这种特性是非常适合于用来管理大尺寸文件的。需要说明的是, 在系统的正常的分页操作过程中,内存映射文件并非一成不变的,它将被定期更新。 如果系统要使用的页面目前正被某个内存映射文件所占用,系统将释放此页面,如果页面数据尚未保存,系统将在释放页面之前自动完成页面数据到磁盘的写入。2 内存映射文件函数( windows)2.1 内存映射文件操作流程(1)调用 CreatFile 打开想
8、要映射的文件,获得句柄hFile ;(2)调用 CreatFileMapping 函数生成一个建立在CreatFile函数创建的文件对象基础上的内存映射对象,得到句柄hFileMap ;(3)调用 MapViewOfFile 函数把整个文件的一个区域或者整个区域映射到内存中,得到指向映射到内存的第一个字节的指针 lpMemory ;(4)用该指针来读写文件;(5)调用 UnmapViewOfFile 来解除文件映射,传入参数为 lpMemory ;(6)调用 CloseHandle 来关闭内存映射文件,传入参数为 hFileMap ;(7)调用 CloseHandle 来关闭文件,传入函数为
9、hFile。2.2 函数说明2.2.1 CreateFile 功能说明:创建或打开一个文件内核对象,这个对象标识了磁盘上将要用作内存映射文件的文件。2.2.2 CreateFileMapping 功能说明:创建一个有名的共享内存。HANDLE CreateFileMapping( HANDLE hFile, / 映射文件的句柄,设为0 xFFFFFFFF以创建一个进程间共享的对象LPSECURITY_ATTRIBUTES lpFileMappingAttributes, / 安全属性DWORD flProtect, / 保护方式DWORD dwMaximumSizeHigh, /对象的大小DW
10、ORD dwMaximumSizeLow, 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 13 页 - - - - - - - - - 内存映射文件测试报告LPCTSTR lpName / 必须为映射文件命名); 2.2.3 MappViewOfFile 功能说明:在创建文件映射对象后使用可以调用MapViewOfFile 函数映射到本进程的地址空间内。LPVOID MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDes
11、iredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, DWORD dwNumberOfBytesToMap ); 参数说明:dwDesiredAccess:用来指定我们想对文件进行的操作,如:FILE_MAP_READ 等。dwFileOffsetHigh 和 dwFileOffsetLow :用来指定打开文件中欲映射的起始偏移位置(映射整个的文件,可指定它们的值为0) 。dwNumberOfBytesToMap :用来指定欲映射的字节数(映射整个的文件,设定该值为0) 。MapViewOfFile()函数允许全部或部分映射文件,
12、在映射时, 需要指定数据文件的偏移地址以及待映射的长度。其中,文件的偏移地址由DWORD 型的参数dwFileOffsetHigh和dwFileOffsetLow组成的 64 位值来指定,而且必须是操作系统的分配粒度的整数倍,对于Windows 操作系统, 分配粒度固定为64KB。当然, 也可以通过如下代码来动态获取当前操作系统的分配粒度:3 测试用例及结果( windows)说明:以下测试环境为windows xp 系统, 2G 内存,个人使用pc 机。3.1 用例 1 3.1.1 测试目的及流程测试目的:对于使用 fopen,fread, fclose 操作文件,与内存映射文件方法,两者效
13、率比较。流程一:(1)使用 fopen 打开文件;(2)使用 fread 读取文件;(3)使用 fclose 关闭文件。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 13 页 - - - - - - - - - 内存映射文件测试报告流程二:(1)使用 CreateFile, CreateFileMapping 创建文件对象和文件映射对象;(2)使用 MapViewOfFile 将文件映射到进程地址空间(整个文件都映射到内存);(3)使用 MapViewOfFile 函数
14、返回的内存指针,访问数据。(4)释放内存映射对象,关闭以上操作产生的句柄。3.1.2 测试结果(1)循环打开800 个大小为 10m 的文件流程第一次第二次第三次第四次流程一5047 313 312 320 流程二375 375 359 375 (2)循环打开40000 个大小为 1k 的文件流程第一次第二次第三次第四次流程一69625 32171 22515 21656 流程二24157 22719 26016 27969 (3)按照“流程一”操作文件,第一次运行耗时较长,以后的操作耗时和内存映射文件耗时相差不多。可能是系统文件缓存原因。3.2 用例 2 3.2.1 测试目的及流程测试目的:
15、比较 fopen,fread,fclose 操作文件,与内存映射文件方法,在打开文件后,多次读取文件的速度。流程一:(4)使用 fopen 打开文件;(5)多次使用 fread 读取文件;(6)使用 fclose 关闭文件。流程二:(5)使用 CreateFile, CreateFileMapping 创建文件对象和文件映射对象;(6)使用 MapViewOfFile 将文件映射到进程地址空间(整个文件都映射到内存);(7)重复使用 MapViewOfFile 函数返回的内存指针,访问数据。(8)释放内存映射对象,关闭以上操作产生的句柄。名师资料总结 - - -精品资料欢迎下载 - - - -
16、 - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 13 页 - - - - - - - - - 内存映射文件测试报告3.2.2 测试结果(1)循环打开100 个不同文件,每打开一次文件,读取文件内容操作1000 次:流程一时间约为:650ms 流程二时间约为:65ms (2)循环打开100 个不同文件,每打开一次文件,读取文件内容操作2000 次:流程一时间约为:1265ms 流程二时间约为:60ms 3.3 用例 3 3.3.1 测试目的及流程测试目的:测试内存映射文件最大同时打开文件的总大小。测试流程:(1)使用 Creat
17、eFile, CreateFileMapping 创建文件对象和文件映射对象;(2)使用 MapViewOfFile 将文件映射到进程地址空间(整个文件都映射到内存);(3)重复以上操作打开不同文件,直到MapViewOfFile 返回错误。(4)关闭以上操作产生的句柄,释放文件映射对象。3.3.2 测试结果文件夹名称文件夹中文件个数内存映射成功文件个数内存映射成功文件总大小test-5m 420 405 2025m test-10m 410 201 2010m 3.4 用例 4 3.4.1 测试目的及流程测试目的:(1)测试是否可以创建多个文件映射内核句柄,但不进行文件映射到内存操作;(2)
18、轮循上一步得到的不同文件映射内核句柄,将对应的文件映射到内存。测试流程:(1)使用 CreateFile,CreateFileMapping 创建多个文件对象和文件映射对象,并将其保存到名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 13 页 - - - - - - - - - 内存映射文件测试报告std:map 中;(2)使用 std:map 中保存的句柄,调用MapViewOfFile 将文件映射到进程地址空间;(3)释放步骤( 2)产生的文件映射对象;(4)重复步骤
19、( 2) ,步骤( 3) ;(5)关闭 std:map 中保存的句柄。3.4.2 测试结果产生多个文件映射句柄,并保存。可依据需要, 对某个文件映射内核句柄进行MapViewOfFile文件映射到内存操作。释放文件映射对象后,重新映射其他文件映射句柄。避免进程地址空间的大小限制。3.5 用例 5 3.5.1 测试目的及流程测试 windows (64 位)下,内存映射大小。测试环境:机器: 192.168.75.238 内存: 64GB 系统: windows server 2003 (64 位)3.5.2 测试结果测试结果:测试文件夹文件个数:共2047 个文件( 47 个 1g 大小的文件
20、2000 个 5m 大小文件)全部映射成功,共映射约58128m(约 56g)文件,未发生错误。4 其他说明(1)因进程地址空间大小有限制,所以内存映射文件也同样有限制,可通过调用MapViewOfFile 时,指定映射的起始偏移位置,来映射部分文件到内存。(2)测试未调查linux 下文件映射的资料。(3)因个人水平,可能存在理解偏差或代码编写有误,会不断改进。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 13 页 - - - - - - - - - 内存映射文件测试
21、报告5 附录(代码)5.1 创建内存映射文件代码/ 1. 创建一个“文件”内核对象HANDLE hFile = CreateFileA(file_path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile = INVALID_HANDLE_VALUE) printf(test_file_mapping | CreateFileA failed (GetLastError = %d). n, GetLastError(); return -1; / 2. 打
22、开一个“文件映射”内核对象HANDLE hFileMap = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, false, NULL); if (hFileMap = NULL) / 如果对象不存在,创建一个“文件映射”内核对象DWORD dwFileSize = 0; hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0,NULL); if (hFileMap = NULL) printf(test_file_mapping | CreateFileMapping fail
23、ed (GetLastError = %d). n, GetLastError(); return -1; / 3. 将数据映射到进程地址空间PVOID pvFileView = MapViewOfFile(hFileMap, FILE_MAP_READ, 0,0,0); if (pvFileView = NULL) printf(test_file_mapping | MapViewOfFile failed (GetLastError = %d). n, GetLastError(); return -1; / 4. 访问或修改数据名师资料总结 - - -精品资料欢迎下载 - - - -
24、- - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 13 页 - - - - - - - - - 内存映射文件测试报告char* pszVal = (char*)pvFileView; / 5. 撤销文件内核对象UnmapViewOfFile(pvFileView); / 6. 关闭文件内核对象和文件映射内核对象CloseHandle(hFileMap); CloseHandle(hFile); 5.2 测试用例 3 代码#include #include iFly_Assert.h #include utils/sutils.h
25、#include #include sp:str_arr res_file; unsigned int tick_count(); const char* get_res_file_name(int cursor); unsigned int tick_count() return :GetTickCount(); const char* get_res_file_name(int cursor) return res_filecursor % res_file.size().c_str(); int main(int argc,char* argv) int ret = 0; SP_ASSE
26、RT(argc = 3); const char* uri = argv1; int loop_count = atoi(argv2); / get resource file list sp:get_file_list(uri, res_file, *, false); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 13 页 - - - - - - - - - 内存映射文件测试报告const char* file_name = ; unsigned int tick
27、_start; unsigned int tick_end; int icount = 0; std:map mapping_map; unsigned long long total_size = 0; double size_m = 0; unsigned int f_size = 0; HANDLE hMapFile = NULL; HANDLE hFile = NULL; for (int i = 0;i loop_count;i+) icount = i; file_name = get_res_file_name(i); hFile = CreateFileA(file_name,
28、 GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile = INVALID_HANDLE_VALUE) printf(CreateFileA failed (GetLastError = %d). n, GetLastError(); break; hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0,NULL); if (hMapFile = NULL) printf(CreateFile
29、Mapping failed,file name = %s,GetLastError = %dn, file_name, GetLastError(); break; mapping_map.insert(std:pair(hFile, hMapFile); f_size = sp:get_file_size(file_name); total_size += f_size; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 13 页 - - - - - - - - -
30、内存映射文件测试报告printf(file num = %d,file size = %dn, (icount+1), f_size); size_m = (double)total_size / (1024*1024); printf(total file size = %llu(%f)n,total_size,size_m); std:map:iterator iter1 = mapping_map.begin(); for (; iter1 != mapping_map.end(); iter1+) HANDLE hFile_m = iter1-first; HANDLE hMappin
31、gFile_m = iter1-second; PVOID p_file_view = MapViewOfFile(hMappingFile_m, FILE_MAP_READ, 0,0,0); if (p_file_view = NULL) printf(MapViewOfFile failed,file name = %s,GetLastError = %dn, file_name, GetLastError(); return -1; char* pszVal = (char*)p_file_view; UnmapViewOfFile(p_file_view); char c100; pr
32、intf(close . ?n); gets(c); std:map:iterator iter2 = mapping_map.begin(); for (; iter2 != mapping_map.end(); iter2+) HANDLE hFile_m = iter2-first; HANDLE hMappingFile_m = iter2-second; CloseHandle(hMappingFile_m); CloseHandle(hFile_m); mapping_map.clear(); system(pause); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 12 页,共 13 页 - - - - - - - - - 内存映射文件测试报告return 0; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 13 页 - - - - - - - - -