mmap:文件映射進內存,及window上的對應方法


工作中遇到一個問題,我們的程序內存占用太大,在目標機器上跑着跑着就崩潰了。經過高手提點,可以把某些內存映射到文件中,從而可以省下一些內存。現在做個記錄方便以后查閱。

在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上只要映射了文件,那么就會釋放掉內存,除非你訪問它。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM