Windows記憶體機制解析(二)

來源:互聯網
上載者:User

                           by leezy_2000

                           2003-10-8 17:01

三、淺談一下Heap

(鑒於Matt Pietrek在它的《Windows 95 系統程式設計大奧秘》對9x系統的heap做了非常詳細的講解,此處涉及的內容將僅限於Win2000)

 

Heap與Stack正好相反,你需要手動來管理每一塊記憶體的申請和釋放(在沒有垃圾收集機制的情況下),而對於C/C++程式員來說,操作Heap的方式實在是太多了點。下面是幾乎所有可以操作堆記憶體的方法的列表:

malloc/free

new/delete

GlobalAlloc/GlobalFree

LocalAlloc/LocalFree

HeapAlloc/HeapFree

 

其中malloc/free由執行階段程式庫提供,new/delete為C++內建的操作符。他們都使用執行階段程式庫的自己的堆。執行階段程式庫的在2000和win9x下都有自己獨立的堆。這也就意味著只要你一啟動進程,你將至少有兩個堆,一個作為進程預設,一個給C/C++執行階段程式庫。

 

GlobalAlloc/GlobalFree和LocalAlloc/LocalFree現在已失去原有的含義,統統從進程預設堆中分配記憶體。

 

HeapAlloc/HeapFree則從指定的堆中分配記憶體。

 

單就分配記憶體而言(new/delete還要管構造和析構),所有這些方式最終要歸結到一點2000和98下都是是HeapAlloc。所以微軟才會強調GlobalAlloc/GlobalFree和LocalAlloc/LocalFree會比較慢,推薦使用HeapAlloc,但由於Global**和Local**具有較簡單的使用介面,因此即使在微軟所提供的原始碼中他們仍被大量使用。必須指出的是HeapAlloc並不在kernel32.dll中擁有自己的實現,而是把所有調用轉寄到ntdll.RtlAllocateHeap。下面這張從msdn中截取的圖(圖2),應該有助於我們理解同堆相關的API。

 

堆內部的運作同SGI STL的分配器有些類似,大體上是這樣,OS為每個堆維護幾個鏈表,每個鏈表上存放指定大小範圍的區塊。當你分配記憶體時,作業系統根據你所提供的尺寸,先確定從那個鏈表中進行分配,接下來從那個鏈表中找到合適的塊,並把其線性地址返還給你。如果你所要求的尺寸,在現存的區塊中找不到,那麼就新分配一塊較大的記憶體(使用VirtualAlloc),再對他進行切割,而後向你返還某一區塊的線性地址。這隻是一個大致的情形,作業系統總在不停的更新自己的堆演算法,以提高堆操作的速度。

堆本身的資訊(包括標誌位和鏈表頭等)被存放在Heap Header中,而堆控制代碼正是指向Heap Header的指標,Heap Header的結構沒有公開,稍後我們將試著做些分析。非常有趣的是微軟一再強調只對toolhelp API有效HeapID其實就是堆控制代碼。

 

原來是準備分析一下堆內部的一些結構的,可後來一想這麼做實用價值並不是很大,所需力氣卻不小。因此也就沒具體進行操作。但這裡把實現監測堆中各種變化的小程式的實現思路公開一下,希望對大家有所協助。這個小程式非常的簡單,主要完成的任務就是枚舉進程內所有的堆的變化情況。由於涉及到比較兩個鏈表的不同,這裡使用了STL的vector容器和某些演算法來減少編碼。同時為了使STL的記憶體使用量不對我們要監測的對象產生幹擾,我們需要建立自己的分配器,以使用我們單獨建立的堆。此外還需要特別注意的一點是由於toolhelp API Heap32Next在運行過程中不允許對任何堆進行擾動(否則他總返回TRUE),導致我們只能使用vector,並預先保留足夠的空間。(訪問堆內部某些資訊的另一種方式是使用HeapWalk API,看個人喜好了)。

 

程式的運行過程是這樣的,先對當前進程中存在的堆進行枚舉,並把結果存入一個set類型的變數heapid1,接下來建立自己的堆給分配器使用,並對進程中存在的堆再次進行枚舉並把結果存入另一個set類型的變數heapid2,這樣就可以調用set_difference求出我們建立堆的ID,再以後列舉隊內部的資訊時將排除這個ID所表示的堆。接下來就可以在兩點之間分別把堆內部的資訊存入相應的vector,比較這兩個vector,就可以得到對應於分配記憶體操作,堆內部的變化情況了。

 


(圖2 from msdn by Murali R. Krishnan)

 

下面是一些懸而未決的問題,那位感興趣可以自己探索。

 

Heap Header結構是什麼樣的?

 

堆內部對記憶體塊的組織方式?(是鏈表麼)

 

每一個小塊的描述資訊在那裡?(如果是鏈表,那就應該有指標使這些小塊彼此相連。)

相關文章

聯繫我們

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