概述
工作中遇到一个问题,我们的程序内存占用太大,在目标机器上跑着跑着就崩溃了。经过高手提点,可以把某些内存映射到文件中,从而可以省下一些内存。现在做个记录方便以后查阅。
在linux上, 用mmap这个方法:
1 int dumpFileDescriptor = open(mmFileName, O_CREAT | O_RDWR, 0755); 2 3 if(dumpFileDescriptor != -1) 4 { 5 void* mappedFileAddress = mmap(NULL, 6 MMAP_ALLOCATOR_SIZE, 7 PROT_READ | PROT_WRITE, 8 MAP_SHARED, 9 dumpFileDescriptor, 10 0); 11 } 12 13 // Do something use mappedFileAddress
函数msysc可以保证把数据同步到了磁盘上
1 msync(mappedFileAddress, MMAP_ALLOCATOR_SIZE, MS_SYNC);
等不用的时候,用unmap函数解除映射
1 munmap(mappedFileAddress, MMAP_ALLOCATOR_SIZE);
然后可以用unlink把映射文件删掉,如果需要的话
1 unlink(mmFileName);
同时我在网上搜了一下,windows下面用CreateFileMapping
1 HANDLE dumpFileDescriptor = CreateFileA(mmFileName, 2 GENERIC_READ | GENERIC_WRITE, 3 FILE_SHARE_READ | FILE_SHARE_WRITE, 4 NULL, 5 OPEN_EXISTING, 6 FILE_ATTRIBUTE_NORMAL, 7 NULL); 8 HANDLE fileMappingObject = CreateFileMapping(dumpFileDescriptor, 9 NULL, 10 PAGE_READWRITE, 11 0, 12 0, 13 NULL); 14 void* mappedFileAddress = MapViewOfFile(fileMappingObject, 15 FILE_MAP_ALL_ACCESS, 16 0, 17 0, 18 MMAP_ALLOCATOR_SIZE); 19 20 // Do something use mappedFileAddress
同步数据到磁盘
1 FlushViewOfFile(mappedFileAddress, MMAP_ALLOCATOR_SIZE);
解除映射
1 UnmapViewOfFile(mappedFileAddress);
Windows上如果想要删除映射文件的话,要先把文件Handle关掉,我一开始不知道这个,怎么删也删不掉。
1 CloseHandle(fileMappingObject); 2 CloseHandle(dumpFileDescriptor); 3 unlink(mmFileName);
两个平台跑起来的效果稍有差别,win32上假如你在heap上申请50M内存(别的什么也不干),把这50M映射了以后可以发现,程序运行时程序占用内存只有几百K,也就是说映射了的内存就跑到磁盘中去了,不占内存空间了,前提是你没有访问这50M空间。Linux上同样的程序,50M还会在内存中,即使你没有访问过它也会在内存里有备份,但是如果你申请的内存很大,比如100M,200M的时候才会释放掉内存空间。我想可能原因是在linux上,只有内存真正不够用时,系统才会把映射到文件中的内存空间释放吧,而windows上只要映射了文件,那么就会释放掉内存,除非你访问它。
转载于:https://www.cnblogs.com/spencer24/archive/2012/08/03/2621786.html
最后
以上就是友好豆芽为你收集整理的mmap:文件映射进内存,及window上的对应方法的全部内容,希望文章能够帮你解决mmap:文件映射进内存,及window上的对应方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复