1. 程式人生 > >在應用程式中使用虛擬記憶體(VirtualAlloc VirtualFree)

在應用程式中使用虛擬記憶體(VirtualAlloc VirtualFree)

此虛擬記憶體非彼虛擬記憶體,此虛擬記憶體實際上指的是虛擬地址空間
LPVOID VirtualAlloc{
LPVOID lpAddress, // 要分配的記憶體區域的地址
DWORD dwSize, // 分配的大小
DWORD flAllocationType, // 分配的型別
DWORD flProtect // 該記憶體的初始保護屬性
};
1.這個函式可以用來對虛擬地址空間進行分配(保留操作MEM_RESERVE)
2.這個函式可以把已經保留的虛擬地址提交到物理儲存器(MEM_COMMIT)
3.這個函式可以使RAM上的內容無效(MEM_RESET)

這個函式的注意點
1.該函式會將傳入lpAddress圓整為64KB(分配粒度)的倍數,然後通過返回值傳一個基地址給你,也就是說該函式返回的值要麼為NULL,要麼為64KB的倍數
2.如果該函式呼叫失敗,會直接返回NULL
3.當函式進行保留操作時,不管使用怎樣的保護屬性,都對提交的保護屬性沒影響,但是,若是想讓系統高效執行,最好讓保留操作和提交操作的保護屬性一致
4.保留操作和提交操作可以同時進行,方法是設定flAllocationType=MEM_RESERVE|MEM_COMMIT
5.使用MEM_RESET標誌可使RAM頁面內容無效,防止系統佔用已用記憶體時,把RAM寫到硬碟的頁檔案,因為這個操作會降低系統的執行效率,但是經過我的測試,這個標誌只在windows2000下有效,在windows xp 或者win7無效(所以這條可以不考慮)

BOOL VirtualFree(
LPVOID lpAddress, // 區域地址
SIZE_T dwSize, // 區域大小,位元組
DWORD dwFreeType // 型別);
看名字都看得出來,這個函式時釋放或者解除虛擬地址到物理儲存器的對映
使用這個函式時只能釋放區域的全部記憶體,但是收回物理儲存器時卻可不受此限制

我們來說說這個函式的應用
假如你有一個表格,為200行X256列,如果一個單元格的結構大小為128位元組,大概需要6553600個位元組的空間,這段記憶體分頁的話大概也需要1600*4K,也就是需要1600個RAM頁,但是可能我們只有幾個單元格填入內容,可以說,記憶體的使用率極低
當然也有其他的方法,就是連結串列,用到一個單元格就申請相應的記憶體,然後連線到連結串列上,但是,這麼做的話,不便於直觀的得到每個單元格的內容,因為我們必須要遍歷連結串列,現在有了虛擬地址空間,我們就可以嘗試新的方法了
1.先申請保留200*256*128個位元組的虛擬地址空間,當然這是一個二維的地址陣列,比如p[200][256];
2.然後,假如第100行100列的單元格填入內容,我們就設法找到p[99][99]的虛擬記憶體地址,然後使用VirtualAlloc把該地址提交到物理儲存器
3.當然就上面的步驟而言還需要做個記憶體檢查(檢查虛擬地址是否已經提交到物理儲存器)
4.設定新的單元格資料結構的成員