背景
原文鏈接:http://blog.csdn.net/ordeder/article/details/31768749
看了幾個內存池的設計,如python,STL,基本上對內存的管理有兩種結構:
1.block,即內存塊,一般和內存頁(pagesize)大小相關。
2.chunk,即內存分片,即在該內存塊上分配要使用的內存空間。
例如python的pyIntObject中使用到的緩衝池的實現: http://blog.csdn.net/ordeder/article/details/25343633
對於內存池的管理,就涉及到了兩種鏈表,
1.內存池的內存塊鏈表
2.對於被使用後回收的內存分片,將被回放與內存分片的鏈表中。
內存池對於一個內存請求(k大小),將提供以2爲倍數的略大於k的內存空間給用戶。對於內存的分片,一般提供2^(i+2) (0<= i <=11)字節大小的不同內存分片。大於2^13B字節的內存的申請請求,內存池是不提供服務,而是直接通過系統的alloc進行分配的,當然這個內存的釋放也不會被回收到內存分片鏈表(freelist)中。
PostGreSQL的內存上下文
每個內存池被他組織成一個內存上下文,而系統中多個內存池是通過一個樹結構對這些內存上下文進行統一的組織和維護。下面是他的內存上下文的一些數據結構關係圖(草圖):
memoryContentData: 作爲內存上下文的節點,多個節點構成系統的內存上下文樹。
AllocSetContext: 作爲內存池的基本數據結構,主要包括內存塊鏈表:*block,和內存分片鏈表的數組Freelist[]
AllocBlockData:內存塊結構,作爲內存塊的頭部信息,其中的兩個char*指針指向了該內存塊的起始和終止的內存地址。aset作爲該內存塊從屬於哪個AllocSetContext的標記。
AllocChunkData:內存分片結構(header),作爲分片的頭部信息,他的具體分片的內存空間緊接其後。頭部信息中有有意思的要屬於void * aset指針了,如果該分片爲空閒(未被分派),那麼aset指針將作爲freelist所用,作爲next指針指向下一個空閒的分片。否則,該內存分片被分配了(不爲空閒)那麼該分片必不在freelist[]的鏈表中,從而aset記錄該分片屬於哪個內存塊(AllocBlockData)