malloc的原理是什麼呢?
這就聯絡到作業系統課程上的記憶體管理那一章節了.
那個時候, 那一章講了很多抽象的理論, 比如最佳分配, 最小分配, 靜態分配, 動態分配, 但是都是紙上談兵.
結合c語言裡的malloc函式, 才能更好地理解.
malloc功能的底層原理是什麼呢?
首先,記得,現在作業系統,是多道系統. 也就是說多個程序同時存在於記憶體中. 而他們又都使用了虛擬記憶體的概念.
接著,在我們管理真正的物理記憶體的時候, 有乙個基本的大前提是, 我們需要有乙個資料結構來管理真實可用的剩餘記憶體空間.(比如上面說的, 分配原則,最佳匹配, 最先匹配等等).所以,我們先要管理空閒記憶體塊的!
因為系統使用的是虛擬記憶體. 所以在32位的系統上面, 每個程序都有2^32次方byte的記憶體. 大前提是我們現在都採用虛擬記憶體管理了.
在多道系統中, 我們所使用的的虛擬記憶體,其實是對映到駐留集(有乙個相近的概念叫工作集)中去的, 所謂的駐留集, 就是作業系統分配給乙個程序的實際使用的物理記憶體空間.
而所謂的malloc功能就是, 根據使用者的虛擬記憶體的需求, 然後去申請物理記憶體. 我猜測malloc底層肯定有呼叫了進入核心的系統呼叫,因為在考研計算機的作業系統那門課裡, 講到, 虛擬記憶體轉換物理記憶體, 使用到位址轉換的. 分配記憶體,是全域性性的事, 肯定必須進入核心.
物理記憶體是要對映到真是的記憶體上的, 所以malloc肯定有乙個功能是把虛擬記憶體對映到物理記憶體上, 而這乙個環節, 就必須進入作業系統呼叫. 放在c語言裡,有乙個概念或者函式,叫 mmap, 做的就是這類工作. 它維護乙個全域性空閒鍊錶, 哪個程序需要了, 就從空閒鍊錶塊摘下乙個塊記憶體. 如果程式呼叫 free, 那麼理論上講, 這個記憶體塊又會重新回到全域性空閒鍊錶中去.
現在,我想說的另外乙個問題是, 如果系統還剩下20m的記憶體,而你想要申請40m記憶體, 那麼malloc會失敗嗎?
理論上會失敗的. 為什麼? 因為malloc分配的是真實的物理記憶體呀!! 都用完了,還拿什麼分配!!!
但是呢, 別忘了, 作業系統使用的是虛擬記憶體, 而如今的記憶體又有幾個級別, 從最抽象的來說, 有cache, 再到我們常說的記憶體條實體, 還有乙個東西我們不能忘記, 那就是記憶體到磁碟的快取區.
還記得我們說的,程序有乙個狀態是suspended嗎?掛起狀態, 如果乙個程序長期阻塞, 那麼就可以被掛起. 那麼這個程序被掛起到什麼地方呢? 肯定是記憶體以外的地方, 在linux系統, 記憶體到磁碟的高速對映區, 就是swap區了. 我們可以對swap區做更多的事情, 如果乙個程序申請了超出系統剩餘的記憶體, 我們還可以在swap區為其分配記憶體!! 既然是預分配, 那也未必立即用的上, 雖然速度可能慢了(在磁碟上,增加了換入換出的時間), 但是慢總比失敗了好.
所以, 如果malloc的原理之一,是可以分配大於物理記憶體剩餘空間的記憶體, 因為會把這些記憶體分配到swap區域,只要swap還有剩餘空間.
另外, 我們知道, 陷入核心是非常高成本的. 而乙個程式設計師可以在程式裡頻繁呼叫 malloc和free, 難道每次都要陷入一次核心嗎? 這樣做明顯不夠高效, 而且記憶體已經月來越便宜了, 反而人們對速度的追求越來越高了. 所以 malloc採用預分配機制, 比如一次要申請2kb,系統可能直接分配給了 4kb, 下次再 malloc一些小的記憶體, 就不用麻煩核心了.
實際上, 有兩個方法, sbrk和brk方法, malloc底層呼叫的就是它, 還有mmap. 總之,就是malloc封裝了這些方法.
[1] malloc底層原理實現
[2] malloc底層分配的兩種機制
malloc 底層實現及Linux記憶體分配原理
1 malloc 函式實在虛擬位址空間中劃分一片區域,而沒有與物理頁對應。1 當開闢的空間小於 128k 時,malloc 的底層實現是呼叫brk 系統呼叫函式來在虛擬位址空間分配記憶體,其主要移動指標 enddata 此時的 enddata指的是 linux 位址空間中堆段的末尾位址,不是資料段的...
malloc的底層實現
每個程序都有乙個虛擬記憶體空間,虛擬記憶體空間通過mmu 儲存器管理單元 對映到真正的物理空間,mmu是乙個硬體,利用儲存在主存中的查詢表翻譯虛擬位址,查詢表由作業系統管理,使用者無法獲取。虛擬位址空間給每個程序乙個假象,就像每個進城擁有4g的執行空間一樣,但是實際在使用記憶體的時候,虛擬位址空間通...
c語言記憶體管理 野指標 malloc
c 語言一共定義四個區塊 區 全域性變數和靜態變數區 棧 堆 針對四個區塊,使用者的記憶體分配也有三種不同的方式 靜態變數區 在 編譯的時候就分配好了,比如全域性變數,被static定義的變數 堆 這需要程式設計師自己分配和釋放,分別使用malloc和free函式 棧 在程式執行的時候,系統會自動的...