▌第一次閱讀本系列的,可以先看:


▌第一次閱讀垃圾回收器系列,可以先看:


▌前文提要:

上一篇做了一些鎖碎的細節優化,包括:
  • 錯誤檢測
  • 釋放地址的次序優化
  • 用巨集作微小的效率優化
  • 用巨集微調函數的使用方式
  • 優化 free_all_register_address
而這篇是 垃圾回收器系列 的最後一篇,沒有代碼,純粹概念、知識。

▌記憶體碎片化:

記憶體碎片化(memory fragmentation),有內部及外部之分,
這裏是指外部碎片(external fragmentation)。
先看看維基百科怎麼說:
外部碎片
當空閒記憶體被分成小區段,分別為不同的行程所使用時,便會出現外部碎片(external fragmentation)。這種情況下,雖然空閒空間足夠大,但是程式沒法使用,因為剩餘空間被分成了大大小小的區段,沒有一塊能夠大到程式可以使用。
另一個說法,就是可分配的連續記憶體不足。
若果不斷地重複、频繁、大量使用 malloc() 和 free() ,
很容易使分配的空間切割了內存,令連續記憶體減少。

内存碎片造成的後果可以很嚴重,即使你的內存空間很大,
假設有 16GB 的空間,故意把分配的內存放置在最不適當的位置。
可分配的連續記憶體 = 16GB / (分配量 + 1) ,若 分配量只有 1KB ,
可分配的連續記憶體也就剩下 15.984 MB 可用了。
當然這是最壞的情況,没有人把分配的內存故意放在最不適當的位置,
分配量也不會只有 1KB 這麼少。

▌如何避免記憶體碎片化:

常見方法如下:
  1. 一次性分配比較大的空間,並且為 2 的指數
  2. 使用內存分頁
  3. 使用內存池
  4. 記憶體緊縮
沒研究過,所以直接放相關網站算了。

▌內存池:

內存池幾乎是記憶體管理終極手段
原理就是 一次性分配的空間,然後自己管理
代替 malloc() 等相關函數的工作。
歸還/釋放甚至只需要一個操作。就是整個內存池本身。
實現方式有很多種,
  • 可以模擬上面的內存分頁,
  • 可以切割成多個可變長度的內存塊(block),用連結串列連結,
    加入標記去決定該內存塊是否已被釋放以及長度等等。
  • 可以另外用一個表去記錄所有分配長度、狀態。
......等等。

就淺談一下,我不是很熟悉。


垃圾回收器系列完結~!


▌參考資料:

碎片化 - 維基百科,自由的百科全書
https://zh.wikipedia.org/zh-hk/%E7%A2%8E%E7%89%87%E5%8C%96
malloc原理和内存碎片化 - ttomqq的专栏 - CSDN博客
https://blog.csdn.net/ttomqq/article/details/71214102
C语言内存碎片如何处理? - 知乎
https://www.zhihu.com/question/51836333
避免實體記憶體碎片化 - 記憶體緊縮 | 程式前沿
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/620508/
浅谈内存池几种设计方式 - yg2362 - C++博客
http://www.cppblog.com/yg2362/archive/2012/07/19/184175.aspx
C++内存池介绍与经典内存池的实现 - Dablelv的博客专栏 - CSDN博客
https://blog.csdn.net/K346K346/article/details/49538975
内存池的实现(一) - bangerlee - 博客园
http://www.cnblogs.com/bangerlee/archive/2011/08/31/2161421.html
記憶池 - 維基百科,自由的百科全書
https://zh.wikipedia.org/zh-hant/%E8%A8%98%E6%86%B6%E6%B1%A0