iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 20
0
自我挑戰組

30 Days 如何把 C 語言偽裝成高階語言 OWO /系列 第 21

Days 20: 垃圾回收器系列:記憶體碎片化、內存池

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

本系列的大綱 傳送門


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

垃圾回收器系列 開始第一篇 傳送門


▌前文提要:

上一篇做了一些鎖碎的細節優化,包括:

  • 錯誤檢測
  • 釋放地址的次序優化
  • 用巨集作微小的效率優化
  • 用巨集微調函數的使用方式
  • 優化 free_all_register_address

而這篇是 垃圾回收器系列 的最後一篇,沒有代碼,純粹概念、知識。


▌記憶體碎片化:

記憶體碎片化(memory fragmentation),有內部及外部之分,
這裏是指外部碎片(external fragmentation)。

先看看維基百科怎麼說:

外部碎片

當空閒記憶體被分成小區段,分別為不同的行程所使用時,便會出現外部碎片(external fragmentation)。這種情況下,雖然空閒空間足夠大,但是程式沒法使用,因為剩餘空間被分成了大大小小的區段,沒有一塊能夠大到程式可以使用。

另一個說法,就是可分配的連續記憶體不足。

若果不斷地重複、频繁、大量使用 malloc()free()
很容易使分配的空間切割了內存,令連續記憶體減少。

可參看 malloc原理和内存碎片化 - ttomqq的专栏 - CSDN博客


内存碎片造成的後果可以很嚴重,即使你的內存空間很大,
假設有 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


上一篇
Days 19: 垃圾回收器系列:鎖碎事項:細節優化
下一篇
Day 21:重溫前置處理器、巨集( #, ## )、預先定義的巨集
系列文
30 Days 如何把 C 語言偽裝成高階語言 OWO /31

尚未有邦友留言

立即登入留言