windows記憶體堆的資料結構

2021-06-17 16:41:57 字數 1570 閱讀 1665

還是緊接著昨天的問題,很想明白到底在記憶體中堆的資料結構到底是怎麼樣的?究竟是不是別人回答的紅黑樹的結構?

在網上搜尋了一番好像也鮮有答案。後來在《0day 安全 軟體漏洞分析技術》一書裡面找到了這個問題的部分答案。

不同平台作業系統對記憶體的管理機制是不一樣的。

上面這本書裡面主要講了對windows2000 - windows xp1 平台的堆管理策略。

對於基本的作業系統中堆的一些特徵,這裡就不再講了。這裡主要說說記憶體中堆的資料結構。

自己畫了張圖給大家看看。。。

(堆的記憶體組織)

現代作業系統的堆資料結構一般包括堆塊和堆表兩類。

堆塊:堆區的記憶體按照不同大小組織成塊,以堆塊為單位進行標識,而不是按照位元組標識。乙個堆塊包括兩個部分:塊首和塊身。

塊首是堆塊頭部的幾個位元組,用來標識這個堆塊自身的資訊,包括本塊的大小、本塊空閒還是占用等資訊;

塊身緊跟在塊首後面的部分,是最終分配給使用者使用的資料區。

我們在程式中很難感覺到塊首的存在。但是正是由於這個塊首的存在,解決了我上幾天提出的為什麼free的位址必須是malloc的位址 還有free的長度是確定的這兩個問題。

因為這些資訊全部包含在塊首裡面,釋放的時候必須進行比對,如果比對結果失敗,那麼自然是無法進行free操作了.(個人猜測,求驗證)

堆表:位於堆區的起始位置,用於索引堆區中堆塊的重要資訊。堆表的資料結構決定了整個堆區的組織方式。堆表在設計時可能會考慮採用平衡二叉樹等高階資料結構用於優化查詢效率。現代作業系統的堆表往往不止一種資料結構。

在windows中,占用態的堆塊被使用它的程式索引,而堆表只索引所有空閒態的堆塊。

重要的堆表有兩種:空閒雙向鍊錶freelist(空表) 和 快速單向鍊錶lookaside(快表)

空閒雙向鍊錶freelist(空表):

堆區一開始的堆表區中有乙個128項的指標陣列(看到有人說把它看成佇列的),被稱作空表索引。該陣列的每一項包含兩個指標,用於表示一條空表。

free[1] 標識了所有堆中所有大小為8位元組的空閒堆塊,之後每個索引指示的空閒堆塊遞增8個位元組。即:

free[2]標識了16個位元組的空閒堆塊。

free[k] 標識了 k * 8 個位元組的空閒堆塊。

指示第1項空表索引比較特殊,從圖中我們也可以看到:這條雙向煉錶鏈入了所有大於等於1024位元組的堆塊(小於512kb),堆塊按照公升序排列。

快速單向鍊錶lookaside(快表)

為什麼叫做快表呢?因為速度快。。。為什麼速度快呢?。。因為這類單向鍊錶中從來不會發生堆塊合併。

結構組織和空表差不多,只是每條快表最多只有4個結點,故很快就會被填滿。

未完待續,下次講講  堆塊的分配,釋放和合併操作。

資料結構 堆

最大堆 最小堆 堆的定義是 n個元素的序列,當且僅當滿足如下關係時被成為堆 1 ki k2i 且 ki k2i 1 或 2 ki k2i 且 ki k2i 1 i 1,2,n 2 當滿足 1 時,為最小堆,當滿足 2 時,為最大堆。若將此序列對應的一維陣列堪稱是乙個完全二叉樹,則2i和2i 1個節點...

資料結構 堆

資料結構 堆的操作和實現 當應用優先順序佇列或者進行堆排序時,一般利用堆來實現。堆是乙個完全 除最底層 外都是滿的 二叉樹,並滿足如下條件 1 根結點若有子樹,則子樹一定也是堆。2 根結點一定大於 或小於 子結點。因為要求堆必須是完全二叉樹,所以可以用線性的資料結構,比如陣列,來實現堆。利用陣列實現...

資料結構 堆

堆常用來實現優先佇列,在這種佇列中,待刪除的元素為優先順序最高 最低 的那個。在任何時候,任意優先元素都是可以插入到佇列中去的,是電腦科學中一類特殊的資料結構的統稱 最大 最小 堆是一棵每乙個節點的鍵值都不小於 大於 其孩子 如果存在 的鍵值的樹。大頂堆是一棵完全二叉樹,同時也是一棵最大樹。小頂堆是...