void *ptr=_emalloc(size);
_efree(*ptr) //釋放記憶體的時候只傳入ptr,並沒有傳入釋放記憶體大小
當我們申請乙個size大小的記憶體的時候,我們多申請一些存起來,下次使用者申請的時候,直接給出相應大小的記憶體即可,這樣減少了使用者態和核心態的切換,提高效率,記憶體**的時候需要知道這個記憶體屬於哪個記憶體頁page,屬於哪個chunk,以便**
chunk記憶體會進行記憶體的預分配,使用mmap分配chunk
記憶體分類: small(30種規格)(size<=3kb)
large(3kbhuge(size>2mb-4kb) //如果申請3mb記憶體,肯定返回比3mb大且2mb倍數記憶體
比如申請大小為7的記憶體,返回的大小為8的記憶體
記憶體分配流程:
如果有現成已經滿足需要的small記憶體就直接返回,否則執行small_slow函式
呼叫mmap會申請大的記憶體
當呼叫samll_slow會先去large記憶體裡面取乙個page,如果page用完了,會從mm_chunk_alloc裡面申請乙個chunk
在small的30個規格中:
比如申請乙個size是7的,我是直接找到包含7的最小的size,比如申請乙個size=8的話,直接申請乙個page,切割成了512個,其中乙份返回回去,剩下的511個掛在
申請small記憶體的時候:1、要找到size最小的規格 2、然後在chunk上申請乙個page,如果乙個page不夠用的話,申請3個page,分成四份,把其中乙份返回給使用者,剩下的儲存在mm_heap
回顧下free_slot欄位的定義:
zend_mm_free_slot *free_slot[zend_mm_bins];
struct zend_mm_free_slot
mm_heap裡面有乙個free_slot,是乙個陣列,掛了0-29,比如我們申請512的8位元組,把第乙個返回,剩下的511個按照鍊錶的方式存起來
思考:為什麼最小是8位元組記憶體塊
可以看出空閒記憶體鍊錶的每個節點都是乙個zend_mm_free_slot結構體,其只有乙個next指標字段;因為8個位元組恰好放next指標,因為需要維護鍊錶,這裡有乙個next指標,需要占用記憶體的
思考:對於8位元組大小的記憶體塊,其next指標就需要佔8位元組的空間,那使用者的資料儲存在**呢?
答案:free_slot是small記憶體的空閒鍊錶,空閒指的是未分配記憶體,此時是不需要儲存其他資料的;當分配給使用者時,此節點會從空閒鍊錶刪除,也就不需要維護next指標了;使用者可以在8位元組裡儲存任何資料;
思考:如何快速找到包含所需記憶體大小的最小規格呢?
答案:
chunk的記憶體對齊
1、怎麼定位快要釋放記憶體是多大的
對任意位址p,如何計算頁號? --2m位元組對齊
chunk的大小為2m,首位址高43位為數字,低21位為0,他的位址為2m的整數倍
如何確保乙個chunk的位址時2m位元組對齊的呢?
我們申請記憶體的時候是由記憶體頁來管理的,我們malloc出來的記憶體位址一定是4k的整數倍,
Redis原始碼分析 記憶體管理
原始碼版本 redis 2.4.4 redis記憶體相關函式都放在zmalloc.h zmalloc.c中 redis中可以使用tcmalloc jemalloc makefile ifeq use tcmalloc yes alloc dep alloc link ltcmalloc alloc ...
FreeRTOS記憶體管理原始碼分析
記憶體管理一直都是重中之重的知識。記憶體管理在freertos系統中是可裁剪可配置的。freertos提供了5種記憶體管理方案。暫時可能分析不完5種方案,今天能寫多少先寫多少,後續有時間了再一點一點的寫吧。5中方案對比如下 方案1 記憶體一旦分配出去就無法 了。記憶體釋放函式是乙個空函式,什麼都沒做...
Libevent 2 1 8原始碼分析 記憶體管理
預設情況下,libevent使用c庫的記憶體管理函式在堆上分配記憶體 其實也就是我們在c中經常使用的malloc realloc和free 當然如果對於記憶體的管理有極高的要求,例如在我們的應用程式中可能頻繁的申請和釋放libevent相關的物件,如果採用預設的記憶體管理,那麼可能就會產生大量的記憶...