2014-09-25 88 views
4

我對小的VirtualAlloc混淆,的VirtualAlloc MEM_COMMIT和MEM_RESERVE

我們可以保留內存使用MEM_RESERVE,然後提交它使用MEM_COMMIT,但我對小搞不清什麼區別時,下面的兩個功能之間使用: ?

m_pvData = VirtualAlloc(NULL, m_nBuffSize, MEM_COMMIT, PAGE_READWRITE); 
m_pvData = VirtualAlloc(NULL, m_nBuffSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 

什麼是選擇第二的benfit

我可以使用下面的功能得到緩衝:

void* pdata = VirtualAlloc(NULL, 64*1024*1024, MEM_COMMIT, PAGE_READWRITE); 
if (pdata == NULL) 
{ 
    cout<<"Last error is "<<GetLastError()<<endl; 
} 

沒有錯誤

+1

因爲第一個在技術上是不正確的。你不能提交沒有保留。 – 2014-09-25 05:59:01

+0

但我可以使用下面的函數來分配緩衝區,如下所示: void * pdata = VirtualAlloc(NULL,64 * 1024 * 1024,MEM_COMMIT,PAGE_READWRITE); if(pdata == NULL) cout <<「Last error is」<< GetLastError()<< endl; } – user2714997 2014-09-25 07:18:46

+0

操作系統可以猜出你的意思。所以沒有區別。 – 2014-09-25 08:18:46

回答

5

的區別是: 與MEM_RESERVE你基本上說的操作系統:「喂,拜託,我需要的虛擬內存頁面的這個連續的塊,你能不能給我一個記憶符合我需求的地址?「

並且操作系統計算你的塊的保留位置。 但它不會分配任何東西。 (要了解操作系統如何執行此操作,只需查看Mark Russinovich撰寫的「Windows Internals 5th」等書籍 - 提示:在Google上搜索有關VAD Trees的信息)。因此,當您保留一塊內存時,操作系統將簡單地在樹上或某個類似的結構上分配一個「節點」,並說這些地址是保留的,就像餐廳的一張桌子一樣,並且不能用於VirtualAlloc()的其他調用。

實際上,當您實際上承諾頁面爲MEM_COMMIT時,操作系統實際上是在您之前保留的塊上分配虛擬內存頁面。 當然,您可以僅在您之前保留的塊上提交頁面。 不這樣做就像預訂坐在餐廳,然後坐在另一張桌子,而不是你保留。

注意:由於您在其上讀/寫(軟頁面錯誤),因此實際上並未分配頁面也不提交它們。這是一個非常有用的優化。注意2:事實上,你可以或者MEM_RESERVE|MEM_COMMIT只是一些有用的東西,所以你不必調用'VirtualAlloc()'API兩次,但實際上它們仍然是兩個非常不同的操作。

注3:本MEM_COMMIT標誌將提交頁面大小邊界上的網頁,同時使用MEM_RESERVEMEM_RESERVE|MEM_COMMIT將預留或預留+提交上比頁面大小,通常在從今天起所有版本的Windows 64K邊界更大的頁面。你可以撥打GetSystemInfo()得到這個號碼。

相關問題