參考資料:https://blog.csdn.net/u014183456/article/details/122031750
記憶體碎片分為內部碎片和外部碎片
- 外部碎片(External Fragmentation):
- 外部碎片是指已分配的記憶體塊之間出現的不連續、無法充分利用的空閒記憶體空間。
- 外部碎片通常發生在動態記憶體分配中,當多次分配和釋放記憶體後,會留下一些小而不連續的未分配空間,這些空間雖然總和足夠大,但無法滿足大塊記憶體的需求。
- 由於外部碎片的存在,可能導致某些記憶體分配請求無法得到滿足,即使總體上有足夠的記憶體空間。
- 內部碎片(Internal Fragmentation):
- 內部碎片是指已分配的記憶體塊中,部分空間沒有被有效利用而浪費掉的情況。
- 內部碎片通常發生在靜態記憶體分配或固定大小記憶體塊分配中。例如,如果申請了一個固定大小的記憶體塊,但實際使用的空間遠小於該記憶體塊的大小,就會產生內部碎片。
- 內部碎片的存在會導致系統整體記憶體利用率下降,因為一些記憶體空間被浪費在了未被使用的部分上。
外部記憶體碎片緩解方式:Linux Buddy分配演算法
內部記憶體碎片緩解方式:slab演算法
Buddy分配演算法:
夥伴記憶體管理演算法的主要步驟包括初始化、分配記憶體、釋放記憶體和合並記憶體。以下是這些步驟的詳細說明:
- 初始化:將整個可用記憶體空間劃分為大小相等的記憶體塊,每個記憶體塊的大小通常是2的冪次方。這些記憶體塊以二叉樹的形式進行組織,其中樹的根節點代表整個可用記憶體空間,而每個節點表示一個特定大小的記憶體塊。
- 分配記憶體:當程式需要分配一塊特定大小的記憶體時,系統會在二叉樹中找到一個最小的、合適的記憶體塊來滿足需求。通常會選擇一個大小略大於需求的記憶體塊,然後將其標記為已分配狀態。
- 釋放記憶體:當程式釋放某塊已分配的記憶體時,系統會將該記憶體塊標記為空閒狀態,並嘗試與其夥伴塊進行合併,形成更大的記憶體塊。
- 合併記憶體:合併是夥伴記憶體管理演算法的關鍵操作,它透過將空閒的記憶體塊與其夥伴塊進行合併,形成更大的記憶體塊。如果合併後的記憶體塊仍然是一個夥伴塊,就可以繼續合併,直到無法再合併為止。
slab演算法:Linux頁表為4k,slab可以將4k繼續拆分為更小的單位來進行管理, 不需要將整個頁面給物件,這樣節省空間。核心中對於頻繁使用的小物件,slab還會進行快取,避免頻繁的記憶體分配與回收