freertos提供了幾個記憶體管理的方案,其中乙個實現較好的方式是heap4。本篇就來形象講述heap4的工作原理。
基本原理:
ucheap是一塊由bss段分配的記憶體區域,heap4的核心記憶體管理特點是只監控空閒塊(free block),不直接監控分配塊。不管是空閒塊還是分配塊,其記憶體空間都由乙個2-word的控制結構開頭,第乙個word是下乙個空閒塊的位址,第二個word用來標記記憶體大小。
空閒塊由xstart開始,依次通過鍊錶連線在一起組成free list。分配空間時,將會從頭(xstart)開始找空間足夠的空閒塊。找到後,將空閒塊原來的控制塊進行修改,第乙個word修改為0,表示該塊已經不是空閒塊。由於現在這個空閒塊的一部分已經被分配,所以第二給我word將被修改為新分配的大小(注意,這裡的新分配的大小不僅僅是malloc時候請求的size,而是要加上前面的控制塊的大小並且進行對其處理。對於每乙個記憶體控制塊而言,其第二個word總是用於被描述其所管理的整個、也就是包含控制塊自身的記憶體的大小),另外,由於該塊已經被分配,將第二個word的最高位標記為1,用於分配標記(因此先前括號中我使用了「描述」這個詞而不是「等於」)。那麼從空閒塊中分離出來剩下的那部分記憶體(如果還有多餘的話)怎麼辦呢,答案是將這部分記憶體分離出來,成為乙個新的空閒塊,鏈結到原有的free list中(注意,這個鏈結過程最後得到的free list的鏈的方向一定是單向的)。然後將控制塊偏移2個word的位址作為分配記憶體指標由返回值返回。
對於記憶體的釋放,將申請得到的記憶體指標往前偏移2個word,然後根據釋放後記憶體是否有可能連續的演算法,嘗試往前或者往後合併記憶體塊,這個過程就這樣帶過,看原始碼的話基本上就能知道這個過程。
整個過程基本上就是這樣,heap4的幾個要點:
空閒塊的第乙個word指向下乙個空閒塊;
空閒塊的第二個word等於這個空閒塊的整個大小;
分配塊的第乙個word為null;
分配塊的第乙個word等於這個分配塊的大小加上flag標記;
空閒塊鍊錶永遠是單向鏈結;
分配記憶體時採用記憶體**演算法,不斷地從空閒塊中申請記憶體;
釋放記憶體時採用記憶體拼接演算法,嘗試拼接記憶體位址連續的空閒塊;
cloud製作了乙個在linux環境下分析記憶體的工具,用於從執行的系統中,將mcu全部記憶體dump出來,找出所有的分配塊和空閒塊。這個工具用於分析系統奔潰情況下freertos系統的記憶體管理是否出現異常,便於記憶體分析快速定位問題。位址如下:
深入剖析C 繼承機制4
2 隱藏基類成員 想想看,如果所有的類都可以被繼承,繼承的濫用會帶來什麼後果?類的層次結構體系將變得十分龐,大類之間的關係雜亂無章,對類的理解和使用都會變得十分困難。有時候,我們並不希望自己編寫的類被繼承。另一些時候,有的類已經沒有再被繼承的必要。c 提出了乙個密封類 sealed class 的概...
深入剖析C 繼承機制 4
2 隱藏基類成員 想想看,如果所有的類都可以被繼承,繼承的濫用會帶來什麼後果?類的層次結構體系將變得十分龐,大類之間的關係雜亂無章,對類的理解和使用都會變得十分困難。有時候,我們並不希望自己編寫的類被繼承。另一些時候,有的類已經沒有再被繼承的必要。c 提出了乙個密封類 sealed class 的概...
Linux的4種鎖機制
互斥鎖 mutex,用於保證在任何時刻,都只能有乙個執行緒訪問該物件。當獲取鎖操作失敗時,執行緒會進入睡眠,等待鎖釋放時被喚醒 pthread mutex init 初始化互斥鎖 pthread mutex destroy 銷毀互斥鎖 pthread mutex lock 以原子操作的方式給乙個互斥...