進程的內存佈局:
Heap的頂端的限制叫作program break,經過系統調用brk活着sbrk能夠想內核申請內存從而改變break,也就是增長或收縮heap的大小。
進程的地址空間所面對的都是虛擬地址,kernel爲每一個進程維護一個page table,創建了虛擬地址空間的頁和物理內存頁或swap空間的映射(虛擬內存或物理內存都是以頁爲單位)。
很重要的一個特色是,虛擬地址空間是連續的!
虛擬內存管理有不少好處:一、進程相互之間或進程與內核之間相互隔離,進程不能操做其餘進程的內存空間,更不能操做內核的空間。二、多個進程能夠共享內存。 (多個進程執行相同的程序,也就是多個進程的text segment所對應的物理內存是同一份),節約內存。三、進程維護的頁表能夠更容易的實現內存保護。(標記page table的entry便可)
虛擬內存這塊讓我想到了,「軟件的不少問題均可以靠加一箇中間層解決」;o(∩_∩)o 哈哈
下面是一個簡單的malloc和free實現,經過系統調用sbrk來實現:
實現細節:
一、在須要的內存塊前面追加一小塊空間,來存儲當前塊的大小(貌似都這樣)
二、維護兩個全局變量,managed_memory_start、所維護內存的起始地址
last_valid_address、所維護內存的最後有效地址,也就是program break
三、free的實現很簡單,標記此塊爲未用
四、malloc實現,遍歷所維護的內存塊,找到合適的就返回,找不到就要求系統分配所要求大小的內存。 html
參考這篇文章: http://www.ibm.com/developerworks/cn/linux/l-memory/index.html linux
這個簡單的內存管理程序有不少缺點:
一、每一次內存不夠時,都要調用sbrk系統調用。sbrk系統調用的單位一般是頁大小的不少倍(頁典型爲4K,sbrk調用最小典型爲128K,數據來自於tlpi),這樣會有效減小系統調用的次數。
二、malloc中的內存大小匹配算法,找到size>=required的塊,會有不少浪費(glibc的實現,則會把大塊分裂,返回用戶須要的,剩餘的放到free list中)。
三、malloc的塊查找算法,是遍歷整個進程空間,效率過低(glibc是雙向鏈表)。
四、mem_control_block的結構中變量is_available只有一位,確是個int類型,佔用空間過多(glibc中只有一個size記錄塊大小,free塊時在塊中分配兩個指針插入到free list雙向鏈表中)。
五、申請的內存並不會返回給內核(glibc在某種狀況下,釋放的內存在heap的頂端造成一大片連續的區域,而且大小達到必定的數值(好比128K,數據來自tlpi),儘可能減小sbrk系統調用的次數)。
前面,後面最重要的文字總結,都是我本身寫的,哈哈~~~