c++相較於其他高階語言來講,能夠方便的進行記憶體管理和操作,是其優勢也是其劣勢,運用得當將使得你編寫的程式效能大大提公升,使用不當也可能給你帶來無盡的麻煩。記憶體池就是其中的重要技術手段之一,下面重點看看常見的兩種記憶體池技術。
此種記憶體池使用廣泛,實現相對簡單,基本能夠滿足大部分時候的需求,使用模板實現,保證了一種記憶體池針對一種型別來分配記憶體,記憶體池中儲存的物件占用空間大小一致,省去了許多在給物件分配記憶體和釋放記憶體時的操作。主要原理如下:
**實現如下:
memory_pool.h
#ifndef untitled_memory_pool_h
#define untitled_memory_pool_h
const size_t blocksize=
4096
;template
<
typename t>
class
memorypool
;typedef slot_ slot_type_;
typedef slot_* slot_pointer_;
slot_pointer_ current_block_;
slot_pointer_ free_slot_;
slot_pointer_ current_slot_;
slot_pointer_ last_slot_;};
memorypool::
memorypool()
:current_block_
(nullptr),
free_slot_
(nullptr),
current_slot_
(nullptr),
last_slot_
(nullptr);
memorypool::
~memorypool()
}void
* memorypool::
allocate()
if(current_slot_>=last_slot_)
return
reinterpret_cast
<
void
*>
(current_slot_++);
}void memorypool::
deallocate
(pointer p)
}#endif
//untitled_memory_pool_h
stl中記憶體分配用到了兩級配置器:
一級配置器:
第一級配置器用於單次分配大於128byte的記憶體,主要以malloc(),free(),realloc()等c函式執行實際的記憶體配置、釋放、重新配置等操作,不多作贅述。
二級配置器:
二級配置器的實現相對複雜一些,但主要執行流程還是比較簡單的:
主要需要搞清楚的是煉表頭陣列和記憶體鍊錶的概念以及refill的工作原理,先看前者:
二級配置器中含有乙個煉表頭陣列,包含了16個成員,每個成員都是乙個煉表頭,而每個煉表頭所指向的鍊錶中的每個節點都指向了一塊可用記憶體,16個煉表頭指向的鍊錶的不同之處在於,它們中的節點指向的可用記憶體大小是不同的,例如:第乙個煉表頭指向的鍊錶中的節點指向的是8byte大小的可用記憶體;第二個煉表頭指向的鍊錶中的節點指向的是16byte大小的可用記憶體,以此類推,如下圖所示:
;當某個記憶體塊為空閒時,該記憶體塊頭部儲存著乙個obj的物件,該obj指向下一塊空閒記憶體塊,如此便構成了乙個空閒記憶體塊的鍊錶,在需要分配記憶體時,先根據需要分配記憶體的大小在煉表頭陣列中找到對應記憶體塊大小的煉表頭(例如需要分配1-8byte記憶體,則取出第乙個煉表頭,若需要分配9-16byte記憶體,則取出第二個,以此類推),之後便用該鍊錶中取出空閒記憶體的指標返回即可,若鍊錶已經沒有可用節點,則呼叫refill。
static
void
*allocate
(size_t n)
my_free_list = free_list +
freelist_index
(n);
//根據需要分配記憶體的大小在煉表頭陣列中找到對應記憶體塊大小的煉表頭
result =
*my_free_list;
if(result ==0)
//若鍊錶已經沒有可用節點
*my_free_list = result -
> free_list_link;
//並把空閒記憶體指標鍊錶的指標指向下乙個資料塊
return
(result);}
;
再看看refill:
template
<
bool threads,
int inst>
void
*refill
(size_t n)
else
}return
(result)
;}
關於chunk_alloc分配記憶體就不多贅述了,stl原始碼解析中有很好的解析,其主要流程就是根據需要分配的記憶體從自己的記憶體池中取出相應的量返回,若記憶體池中存量不夠,則繼續向系統申請來進行補充。
以上兩種記憶體池技術各有優劣,第一種在實現上更為簡單,流程清晰簡介,但只適用於針對每種固定大小的型別;第二種為stl中使用,基本能夠兼顧適配不同申請記憶體大小的需求和效能兩者,但整體實現相對複雜,理解起來需要一定的時間。
AsyncTask兩種執行緒池
asynctask兩種執行緒池 api 3.0以後 1 thread pool executor,非同步執行緒池 使用 首先建立乙個繼承自asynctask的myasynctask類,然後呼叫 1 myasynctask asynct newmyasynctask task 2 asynct.exe...
兩種記憶體碎片
一 內部碎片 內部碎片就是已經被分配出去 能明確指出屬於哪個程序 卻不能被利用的記憶體空間 內部碎片是處於區域內部或頁面內部的儲存塊。占有這些區域或頁面的程序並不使用這個儲存塊。而在程序占有這塊儲存塊時,系統無法利用它。直到程序釋放它,或程序結束時,系統才有可能利用這個儲存塊。二 外部碎片 外部碎片...
棧的兩種C 實現
棧 stack 是限制插入和刪除只能在乙個位置上進行的表,該位置是表的末端,叫做棧的頂 top 它是後進先出 lifo 的。對棧的基本操作只有push 進棧 和pop 出棧 兩種,前者相當於插入,後者相當於刪除最後的元素。棧本質上是一種受限制的表,所以可以使用任何一種表的形式來實現它,最常用的是使用...