1. 程式人生 > 實用技巧 >對malloc和free的思考

對malloc和free的思考

>>> hot3.png

程序的記憶體佈局:


Heap的頂端的限制叫做program break,通過系統呼叫brk活著sbrk可以想核心申請記憶體從而改變break,也就是增加或收縮heap的大小。
程序的地址空間所面對的都是虛擬地址,kernel為每個程序維護一個page table,建立了虛擬地址空間的頁和實體記憶體頁或swap空間的對映(虛擬記憶體或實體記憶體都是以頁為單位)。
很重要的一個特點是,虛擬地址空間是連續的!
虛擬記憶體管理有很多好處:1、程序相互之間或程序與核心之間相互隔離,程序不能操作其他程序的記憶體空間,更不能操作核心的空間。2、多個程序可以共享記憶體。 (多個程序執行相同的程式,也就是多個程序的text segment所對應的實體記憶體是同一份),節約記憶體。3、程序維護的頁表可以更容易的實現記憶體保護。(標記page table的entry即可)
虛擬記憶體這塊讓我想到了,“軟體的很多問題都可以靠加一箇中間層解決”;o(∩_∩)o 哈哈
下面是一個簡單的malloc和free實現,通過系統呼叫sbrk來實現: 實現細節: 1、在需要的記憶體塊前面追加一小塊空間,來儲存當前塊的大小(貌似都這樣) 2、維護兩個全域性變數,managed_memory_start、所維護記憶體的起始地址 last_valid_address、所維護記憶體的最後有效地址,也就是program break 3、free的實現很簡單,標記此塊為未用

4、malloc實現,遍歷所維護的記憶體塊,找到合適的就返回,找不到就要求系統分配所要求大小的記憶體。

參考這篇文章: http://www.ibm.com/developerworks/cn/linux/l-memory/index.html


這個簡單的記憶體管理程式有很多缺點: 1、每一次記憶體不夠時,都要呼叫sbrk系統呼叫。sbrk系統呼叫的單位通常是頁大小的很多倍(頁典型為4K,sbrk呼叫最小典型為128K,資料來自於tlpi),這樣會有效減少系統呼叫的次數。 2、malloc中的記憶體大小匹配演算法,找到size>=required的塊,會有很多浪費(glibc的實現,則會把大塊分裂,返回使用者需要的,剩餘的放到free list中)。 3、malloc的塊查詢演算法,是遍歷整個程序空間,效率太低(glibc是雙向連結串列)。 4、mem_control_block的結構中變數is_available只有一位,確是個int型別,佔用空間過多(glibc中只有一個size記錄塊大小,free塊時在塊中分配兩個指標插入到free list雙向連結串列中)。 5、申請的記憶體並不會返回給核心(glibc在某種情況下,釋放的記憶體在heap的頂端形成一大片連續的區域,並且大小達到一定的數值(比如128K,資料來自tlpi),儘量減少sbrk系統呼叫的次數)。
前面,後面最重要的文字總結,都是我自己寫的,哈哈~~~


轉載於:https://my.oschina.net/astute/blog/91983