Windows核心編程學習筆記–第18章

來源:互聯網
上載者:User

 

第18章堆

先講優缺點,產生興趣,再講堆是什麼,怎麼用。

18.1進程的預設堆

18.2為什麼要建立額外的堆

18.3如何建立額外的堆

18.4其他堆函數

---------標記的為自己的分析。

先說說優缺點:堆非常適合分配大量的小型資料。與虛擬記憶體和記憶體對應檔相比,堆是用來管理鏈表和樹的最佳方式。優點:不必理會分配粒度和頁面邊界這類事情。缺點:分配和釋放記憶體塊的速度比其他方式慢,且無法再對實體儲存體器的調撥和撤銷調撥進行直接控制。

堆是什麼:堆就是一塊預訂的地址空間地區。剛開始,地區內的大部分頁面都沒有調撥實體儲存體器。隨著我們不斷從堆中分配記憶體,堆管理器會給堆調撥越來越多的實體儲存體器。這些實體儲存體器始終是從頁分頁檔中分配的。釋放堆中的記憶體塊時,堆管理器會撤銷已調撥的實體儲存體器。

-------說明有個堆管理器,調撥和釋放實體儲存體器都由堆管理器來控制,而且只能從頁分頁檔中分配。程式員只用從堆中分配記憶體,由堆管理器來調撥和釋放實體儲存體器。

 

18.1進程的預設堆

定義:進程初始化時,系統會在進程地址空間中建立一個堆。預設大小為1M。

應用:許多windows函數會用到進程的預設堆。當程式有多個線程同時調用windows函數時,對預設堆的訪問必須依次進行。即:系統保證一次只讓一個線程從預設堆中分配或釋放記憶體塊。

一個進程同時可有多個堆,進程在整個生命週期內可建立和銷毀這些堆。但,預設堆在進程開始之前由系統自動建立,進程終止後自動銷毀,不受人為控制。每個堆都有一個用來標識自己的堆控制代碼,所有分配和釋放記憶體塊的堆函數都會在參數中用到這個堆控制代碼。GetProcessHeap可獲得進程的預設堆的控制代碼。---------有啥用,又不能控制。

18.2為什麼要建立額外的堆

         這些原因可能為:

對組件進行保護

更有效記憶體管理

局部訪問

避免線程同步的開銷

快速釋放

18.3如何建立額外的堆

HANDLE  HeapCreate(

         DWORD  fdwOptions,

         SIZE_T  dwInitialSize,//一開始要調撥給堆的位元組數。

         SIZE_T  dwMaximumSize);//表示堆所能增長到的最大大小。若為0,則堆沒有指定的上限。從堆中分配記憶體會使堆不斷增大,直到用盡所有的實體儲存體器為止。

從堆中分配記憶體時,HeapAlloc函數執行以下操作:

1)遍曆已指派記憶體的鏈表和閑置記憶體的鏈表。

2)找到一塊足夠大的閑置記憶體塊。

3)分配一塊新的記憶體,也就是將剛找到的閑置記憶體塊標記為已指派。

4)將新分配的記憶體塊添加到已指派記憶體的鏈表中。

fdwOptions取值:

HEAP_NO_SERIALIZE:盡量不用。不指定HEAP_NO_SERIALIZE標識時,只允許一個線程獨佔堆及其鏈表的訪問,直到所必須的操作都已經完成(即HeapAlloc的四步操作全部完成)。若且唯若進程中的線程獨佔訪問堆(通過同步機制或者僅有一個線程訪問堆)時,才可指定此屬性。

HEAP_GENERATE_EXCEPTIONS:每當堆中分配或重新分配記憶體塊失敗時,拋出一個異常。

HEAP_CREATE_ENABLE_EXCUTE:可在堆中存放可執行代碼。

18.3.1從堆中分配記憶體塊

PVOID  HeapAlloc(

HANDLE  hHeap,

DWORD  fdwFlags,

SIZE_T  dwBytes);

fdwFlags取值:

HEAP_ZERO_MEMORY:在HeapAlloc返回前把記憶體塊的內容都清零。

HEAP_GENERATE_EXCEPTIONS:同HeapCreate。HeapCreate指定時,此處不必指定,整個堆有這個屬性,從此堆分配的記憶體都具有此屬性。HeapCreate未指定,此處指定時,僅分配到達記憶體有此屬性,堆中其他記憶體無此屬性。

HEAP_NO_SERIALIZE:同上,不要用。

在分配大塊記憶體(1MB或更多)時應避免使用堆函數,用VirtualAlloc。

         若分配大量不同大小的記憶體塊,那麼堆管理器內部用來處理分配請求的預設演算法可能會產生地址空間片段:由於所有可用記憶體塊都不夠大,因此系統無法找到一塊足夠大的閑置記憶體塊。在xp和server2003之後的版本中,可強制作業系統在分配記憶體時使用一種叫低片段堆的演算法。在多處理器的機器上,低片段堆的效能得到了極大的提高。下面代碼用來切換到低片段堆:

ULONG  HeapInformationValue = 2;

if (HeapSetInformation(hHeap, HeapCompataibilityInformation, &HeapInformationValue, sizeof(HeapInformationValue))

{//hHeap is turned into a low fragmentation heap}

else

{//hHeap can’t be turned into a low fragmentation heap.Maybe because it has been created with the HEAP_NO_SERIALIZE flag}參考P498

18.3.2調整記憶體塊的大小

PVOID  HeapReAlloc(

HANDLE  hHeap,

DWORD  fdwFlags,

PVOID  pvMem,

SIZE_T  dwBytes);

18.3.3獲得記憶體塊的大小

         分配一塊記憶體後,可調用HeapSize來得到這塊記憶體的實際大小:

SIZE_T  HeapSize(

HANDLE  hHeap,   //堆標識

DWORD  fdwFlags,        //0或HEAP_NO_SERIALIZE

LPCVOID  pvMem);        //記憶體塊的地址

18.3.4釋放記憶體塊

BOOL  HeapFree(

HANDLE  hHeap,

DWORD  fdwFlags,        //0或HEAP_NO_SERIALIZE

PVOID  pvMem);釋放記憶體可能會使堆管理器撤銷一些已經調撥的實體儲存體器。

18.3.5銷毀堆

BOOL  HeapDestroy(HANDLE  hHeap);

18.3.6在C++中使用堆:樣本了如何在一個堆中分配所有執行個體。

18.4其他堆函數:P503

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.