2012-07-16 83 views
3

我知道有一個元數據存儲在free(),realloc()期間僅在提供指針時使用的輔助信息。堆管理

我對堆沒有什麼疑問。

  • 堆棧是按進程分配的。毫無疑問,但不知道堆。其他每個進程是否全局維護一個堆信息,會有一些機制保存關於該特定進程的分配內存的信息。

  • 堆信息將如何維護?我猜哈希機制。我Google搜索並嘗試過。他們中的大多數將其解釋爲具體實現..就像那樣。
+0

列出的相關細節:進程是不同於一個線程。[雖然每個線程都有自己的堆棧,但線程共享內存,包括堆](http://stackoverflow.com/q/1762418/274261)。過程不。 – ArjunShankar 2012-07-16 09:30:36

+0

k @ArjunShankar。離開線程。請考慮過程。我的目標是要知道堆是如何完成的。 – Jeyaram 2012-07-16 09:41:14

+0

好的。我建議你考慮編輯你的問題。由於使用'線程/進程'造成的混淆,已經寫了一個答案。 – ArjunShankar 2012-07-16 09:51:36

回答

4

堆,就像堆棧一樣,是一個進程,和一個(幾乎)純粹的用戶空間的東西。

堆管理器使用系統調用sbrk通知操作系統它打算增加所需的內存量。除了將一系列頁面從「未知」改爲「現有,零,從未訪問過」之外(這實際上意味着他們仍然不存在,但是操作系統假裝他們這樣做)除此之外沒有什麼區別。當第一次訪問頁面時,它會發生故障,操作系統從零池中抽取零頁面。
(它可能稍微複雜一點,因爲如果大量內存已經從頂層釋放,堆管理器可能也會縮小數據段,但基本上它就像這樣簡單)。

這已經是所有操作系統都知道堆了。其他一切,比如分割塊,將釋放的塊放到列表或類似的結構中,以及重用塊會發生在堆管理器內部,堆管理器直接或間接地(例如,作爲glibc的一部分)發生在程序中。

堆管理器究竟在做什麼是依賴於實現的,至少存在六個衆所周知的不同malloc實現,它們以不同的方式工作。參見例如this onethis onethis one

堆棧以相同或類似的方式工作。某個內存範圍最初是「保留」的,沒有實際保留任何內容(即不創建頁面)。幾頁提交(即創建),最後一頁是寫保護或不存在的,這是以特殊方式記住的。當堆棧增長以便觸碰最後一頁時,會發生故障。然後從零池中取出一個新頁面,前提是該堆棧仍處於其允許的大小範圍內。

當進程終止時,所有對這些頁面的引用都會被刪除,並且(假設它們不與另一個仍然存有引用的進程共享)交給一個低優先級的後臺任務,將其歸零並將它們添加到「零池「。

1

是的,堆也是每個進程。

爲了減少鎖爭用,有一些堆實現使用每線程堆,但這是(用戶空間)堆管理器的實現細節。