Windows CE虛擬內存

=============================================================

標題:Windows CE虛擬內存

備註:

日期:2011.3.12

姓名:朱銘雷

=============================================================

獲取系統內存信息:

       MEMORYSTATUS memstatus;

       memstatus.dwLength = sizeof(MEMORYSTATUS);

       GlobalMemoryStatus(&memstatus);

結果:

dwMemoryLoad字段表示當前內存使用率爲34%,但這個數字不精確。

dwTotalPhys字段表示當前的程序內存總計爲52104KB53354496byte)。

dwAvailPhys字段表示當前可用的程序內存還剩34736KB)(35569664byte)。

dwTotalVirtual字段表示當前程序可以使用的虛擬地址空間總量爲32M,可用的還剩27.8M

我測試的系統是Windows CE 5.0,系統中最多可以有32個進程,每個進程可以使用的虛擬地址空間爲32M。這種情況在Windows CE 6.0中得到了很大改善,最大進程數貌似是32K個,每個進程可以使用的虛擬地址空間爲2G

Windows CE 5.0的進程虛擬地址空間分配圖:

 

Windows CE 6.0的進程虛擬地址空間分配圖:

 

虛擬內存

1 VirtualAlloc 分配虛擬內存

       const int PAGESIZE = 4096;

       LPVOID pMem1 = 0, pMem2 = 0;

       pMem1 = VirtualAlloc(NULL, PAGESIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

       pMem2 = VirtualAlloc(NULL, PAGESIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

       這段代碼的本意是想分配兩個單頁(4K字節)大小的虛擬內存,第一個參數設置爲NULL,由系統來決定在何處分配內存。訪問權限是可讀可寫。

但實際調試時發現,每次提交一個頁面大小的虛擬內存時,實際上分配的是0x1000064K字節)大小的虛擬內存,原因是進行了64KB字節的邊界對齊,這就造成了虛擬內存空間的嚴重浪費。理想一點的解決方法是,首先“保留”(MEM_RESERVE)一塊64KB(或其整數倍)字節大小的虛擬內存,然後在需要的時候提交該區域的一個頁面或幾個頁面。

       const int PAGESIZE = 4096;

       LPVOID pMemBase = 0, pMem1 = 0, pMem2 = 0;

       pMemBase = VirtualAlloc(NULL, PAGESIZE*16, MEM_RESERVE, PAGE_NOACCESS);

       pMem1 = VirtualAlloc(pMemBase, PAGESIZE, MEM_COMMIT, PAGE_READWRITE);

       pMem2 = VirtualAlloc((PBYTE)pMemBase+PAGESIZE, PAGESIZE, MEM_COMMIT, PAGE_READWRITE);

調試時,可以看出pMem1所指的虛擬內存,實際分配了0x10004K字節)大小的虛擬內存。

      

2 VirtualFree回收釋放虛擬內存

回收是使頁面處於“保留”狀態,取消虛擬內存到物理內存之間的映射。上面那段代碼申請了64KB大小的虛擬內存,其中8KB(兩頁)處於“提交”狀態,剩餘處於“保留”狀態。這時先回收已“提交”部分,再整體“釋放”。如果區域中既有“提交”頁面,又有“保留”頁面,則VirtualFree將失敗。

VirtualFree(pMem1, PAGESIZE, MEM_DECOMMIT);

VirtualFree(pMem2, PAGESIZE, MEM_DECOMMIT);

       VirtualFree(pMemBase, 0, MEM_RELEASE);

3 VirtualProtect改變訪問權限

VirtualProtect只能改變已“提交”頁面的訪問權限。

DWORD dwOldProtect = 0;

VirtualProtect(pMem1, PAGESIZE, PAGE_READONLY, &dwOldProtect);

4 VirtualQuery查詢訪問權限

       MEMORY_BASIC_INFORMATION memInfo;

       VirtualQuery(pMemBase, &memInfo, sizeof(MEMORY_BASIC_INFORMATION));

 

BaseAddress是傳遞給VirtualQuery函數準備查詢權限的頁地址,AllocationBaseVirtualAlloc分配虛擬內存時的初始地址,AllocationProtect1PAGE_NOACCESS,說明該區域最初分配時訪問權限爲PAGE_NOACCESSRegionSize包含從BaseAddress地址開始,具有相同屬性的頁的字節大小,這裏爲0x10004KB)字節大小,實際上就是pMem1所指的區域大小,其屬性PAGE_READONLY(經過上面更改)與pMem2所指的區域PAGE_READWRITE不同。State0x1000MEM_COMMIT)表明該區域中的頁面處於“提交”狀態。Protect0x02PAGE_READONLY,是該區域當前的訪問權限。Type0x20000MEM_PRIVATE),表明該區域爲當前進程私有。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章