Windows API 之 VirtualAlloc(未完)

來源:互聯網
上載者:User

標籤:

Reserves, commits, or changes the state of a region of pages in the virtual address space of the calling process. Memory allocated by this function is automatically initialized to zero.

LPVOID WINAPI VirtualAlloc(  _In_opt_ LPVOID lpAddress,  _In_     SIZE_T dwSize,  _In_     DWORD  flAllocationType,  _In_     DWORD  flProtect);

 

為了更好的理解VirtualAlloc,我們需要先瞭解下虛擬記憶體技術原理。

Windows的記憶體結構是深入理解Windows作業系統如 何運作的最關鍵之所在,通過對記憶體結構的認識可清楚地瞭解諸如進程間資料的共用、對記憶體進行有效管理等問題,從而能夠在程式設計時使程式以更加有效方 式運行。Windows作業系統對記憶體的管理可採取多種不同的方式,其中虛擬記憶體的管理方式可用來管理大型的對象和結構數組。

在Windows系統中,任何一個進程都被賦予其自己的虛擬位址空間,該虛擬位址空間覆蓋了一個相當大的範圍,對於32位進程,其地址空間為 2^32=4,294,967,296 Byte,這使得一個指標可以使用從0x00000000到0xFFFFFFFF的4GB範圍之內的任何一個值。雖然每一個32位進程可使用4GB的地址 空間,但並不意味著每一個進程實際擁有4GB的物理地址空間,該地址空間僅僅是一個虛擬位址空間,此虛擬位址空間只是記憶體位址的一個範圍。進程實際可以得到的實體記憶體要遠小於其虛擬位址空間。進程的虛擬位址空間是為每個進程所私人的,在進程內啟動並執行線程對記憶體空間的訪問都被限制在調用進程之 內,而不能訪問屬於其他進程的記憶體空間。這樣,在不同的進程中可以使用相同地址的指標來指向屬於各自調用進程的內容而不會由此引起混亂。

在進程建立之初並被賦予地址空間時,其虛擬位址空間尚未分配,處於空閑狀態。這時地址空間內的記憶體是不能使用的,必須首先通過VirtualAlloc()函數來分配其內的各個地區,對其進行保留

其參數lpAddress包含一個記憶體位址,用於定義待分配地區的首地址。通常可將此參數設定為NULL,由系統通過搜尋地址空間來決定滿足條件的未保留 地址空間。這時系統可從地址空間的任意位置處開始保留一個地區,而且還可以通過向參數flAllocationType設定MEM_TOP_DOWN標誌 來指明在儘可能高的地址上分配記憶體。如果不希望由系統自動完成對記憶體地區的分配而為lpAddress設定了記憶體位址(必須確保其始終位於進程的使用者模式分區中,否則將會導致分配的失敗), 那麼系統將在進行分配之前首先檢查在該記憶體位址上是否存在足夠大的未保留空間,如果存在一個足夠大的空閑地區,那麼系統將會保留此地區並返回此保留地區的 虛擬位址,否則將導致分配的失敗而返回NULL。這裡需要特別指出的是,在指定lpAddress的記憶體位址時,必須確保是從一個分配粒度的邊界處開始。

 

記憶體的“保留”與“提交”:

Win32為系統中的每一個應用程式(進程)提供一個獨立的、2   GB的使用者地址空間。對於應用程式來說,好象是有2   GB的可用記憶體(實際上在Windows95/98,NT,Win2000   Advanced   Server/Enterprise   Server   上的記憶體配置略有不同),而不用考慮實際可用的實體記憶體的量。如果某個應用程式要求的記憶體比可用的記憶體更多時,Win32是這樣滿足這種要求的,它從這個 和/或其他的進程把非關鍵記憶體分頁(paging)到一個頁檔案,並且釋放這些實體記憶體頁

在任意給定的時間,進程中每個地址都可以被當作是自由的、保留的或已提交的進程開始時,所有地址的都是自由的,意味著它們都是自由空間並且可以被提交到 記憶體,或者為將來使用而保留起來,但是它們不能存取(read/write)。在任何自由的地址能夠被使用前,它必須首先被分配為保留的或已提交的。  

當在一個進程中保留地址時,沒有實體記憶體頁被提交,並且,也許更為重要的是,在頁檔案中沒有為備份該記憶體而保留空間。而且,保留一個位址範圍將不會保證將來會有可用的實體記憶體來提交給這些地址。實際上,它只是儲存了一個指定的自由地址地址,一直到需要使用它時,而阻止了其它分配對該段地址的請求如果沒有 這種類型的保護,那麼常式操作(routine   operations),例如載入一個DLL或者資源,可能會佔有指定的地址,並且危害以後對它的使用。  要使用保留的地址,記憶體首先必須被提交給該地址。提交記憶體到地址與保留記憶體相類似.調用VirtualAlloc,並且在調用時設定 dwAllocation參數等於MEM_COMMIT。在這一時刻,資源被提交到地址上。每一次,記憶體可以按一頁的大小被提交。能夠被提交的最大記憶體值 僅僅取決於連續的自由或者保留地址的最大範圍(但兩者不可組合在一起),無須考慮系統的可用實體記憶體的大小。  

當記憶體被提交時,記憶體物理頁被分配,並且該段空間被保留在在一個頁檔案中。也就是說,已提交的記憶體頁總是以實體記憶體頁或者在已經被分頁的磁碟上的頁檔案的 形式存在。當提交一個大塊記憶體時,在初始階段,其部分或者全部記憶體沒有駐留在實體記憶體中也是有可能的。某些記憶體頁一開始駐留在頁檔案中,直到它被訪問。在 系統中,一旦記憶體頁已提交,虛擬記憶體管理器象對待所有其它的記憶體頁一樣對待它們。  
 在Win32虛擬記憶體系統中,使用了頁表(page  tables)來訪問實體記憶體頁。每個頁表本身也是一個記憶體頁,象已提交的頁一樣。偶而,當提交記憶體時,同時還必須對頁表分配附加的頁。所以,提交一頁記憶體的請求可能需要為頁表分配一頁,為請求的頁分配一頁,並且在頁檔案中需要兩頁空間來備份這些頁中的每一頁。因此,VirtualAlloc完成一個記憶體提交請求所需要的時間變化很大,它取決於系統的狀態以及請求的空間大小。

 

“記憶體 - 提交大小:為某進程使用而保留的虛擬記憶體的數量。
對於已提交的頁面,系統會根據總的記憶體使用量情況來調度它們。當實體記憶體緊張時,系統會選擇一些頁面,將它們換出到記憶體檔案中,待下次使用的時候,再將它們換回來。通常情況下,應用程式並不需要幹預系統的頁面調度機制。在一些特殊情況下,應用程式也可以通過VirtualLock函數來鎖住已提交頁面,使得它們總是留在實體記憶體中;以後再調用VirtualUnlock函數來結束這種鎖定。”

關鍵字:

記憶體保留 記憶體提交

參考:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa366887%28v=vs.85%29.aspx

http://www.yesky.com/67/1753067.shtml

http://super-man-woman.blog.163.com/blog/static/3789803820098532317144/

 

Windows API 之 VirtualAlloc(未完)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.