首先說明,這些還僅限於我的理解階段,可能有很多錯誤或者問題,歡迎各位指正以便於補足我的理解。
大家都或多或少的知道,memcached裏面有一套特殊的內存管理機制。長話短說,即內存池。當某個數據要被存儲時,首先系統根據該數據大小去找已分配而未使用的內存,如果有,則把數據存儲在這塊內存區域。
例如 188
數據(200) ----- 210
220
其中三塊188,210,220大小的內存區域都是已經分配的區域,但是沒有被使用。當數據200大小要存儲時,則選擇最切近的210大小去存儲數據,即便有10大小空閒,也無妨。
如果沒有空閒內存區域,則會根據數據大小malloc一個內存,用來存儲數據。
當內存使用後,不用釋放內存,該內存會被放入一個空閒的隊列供後來者使用。
python中也有類似機制。不過python採用的block-pool-arean是預先分配內存大小的。大家可以在源碼中看到。
其中,block的分配上限是256。
內存的區間 大小 索引
* 1-8 8 0
* 9-16 16 1
* 17-24 24 2
* 25-32 32 3
* 33-40 40 4
* 41-48 48 5
* 49-56 56 6
* 57-64 64 7
* 65-72 72 8
* ... ... ...
* 241-248 248 30
* 249-256 256 31
然後當數據分配時在預分配的內存中尋找適合大小的區域。原則與memcached有點類似。
memcached這麼做,主要是根據數據大小來避免頻繁申請內存導致的內存碎片。而python這裏也類似。但我頗不理解的是,在PyObject_malloc分配時,大小與Py_ssize_t有直接關係。
如果超過這個大小,意味着只能用Pymem_malloc分配,你可以認爲其於c的malloc類似。
由於很多py程序中無法直接去操作內存,無法直接去控制內存的malloc與free,因此可能連最後一次改正的機會都沒有了。
這樣便導致,如果您的項目需要頻繁的操作內存,而且內存超過這些限制,可能便導致一些內存碎片的問題。