java构建内存池队列_内存池完整实现代码及一些思考
為了提高效率和有效的監(jiān)控內(nèi)存的實(shí)時(shí)狀態(tài),我們采取了內(nèi)存池的思想來解決效率與對內(nèi)存實(shí)現(xiàn)監(jiān)控的問題。
網(wǎng)上查找到了一些方案,根據(jù)自己的理解實(shí)現(xiàn)了應(yīng)用。
我們什么時(shí)候要調(diào)用到內(nèi)存池,
1,當(dāng)我們頻繁的申請釋放同樣數(shù)據(jù)大小的內(nèi)存空間,我們可以用比動態(tài)new更有效方式來管理內(nèi)存時(shí),我們應(yīng)該用內(nèi)存池來提高效率。
2,當(dāng)我們需要知道內(nèi)存實(shí)時(shí)的申請狀態(tài),以便于對于服務(wù)器內(nèi)存狀態(tài)做實(shí)時(shí)預(yù)警時(shí),我們可以用內(nèi)存池的接口,來給內(nèi)存增加監(jiān)控。
實(shí)現(xiàn)的特點(diǎn):
1,內(nèi)存池內(nèi)存單元大小可以動態(tài)定義,實(shí)現(xiàn)多級內(nèi)存池。
2,申請效率很高,單元測試下是普通new/delete的4倍左右,當(dāng)然具體性能還應(yīng)機(jī)器類別而異。
MemoryPool.h 的實(shí)現(xiàn)
//該內(nèi)存池理論來自于IBM文章,http://www.ibm.com/developerworks/cn/linux/l-cn-ppp/index6.html
//作者馮宏華,徐瑩,程遠(yuǎn),汪磊享有論文著作權(quán),由2011-06-06 konyel lin根據(jù)相關(guān)代碼和理論進(jìn)行優(yōu)化修改。
#include
#include
//內(nèi)存對齊值,可以根據(jù)機(jī)器取指長度進(jìn)行設(shè)置
#define MEMPOOL_ALIGNMENT 4
#define USHORT unsigned short
#define ULONG unsigned long
struct MemoryBlock
{
USHORT nSize;
USHORT nFree;
USHORT nFirst;
USHORT nDummyAlign1;
MemoryBlock* pNext;
char aData[1];
static void* operator new(size_t,USHORT nTypes, USHORT nUnitSize){
return ::operator new(sizeof(MemoryBlock) + nTypes * nUnitSize);
}
static void operator delete(void *p, size_t){
::operator delete (p);
}
MemoryBlock (USHORT nTypes = 1, USHORT nUnitSize = 0);
~MemoryBlock() {}
};
class MemoryPool
{
private:
MemoryBlock* pBlock;
USHORT nUnitSize;
USHORT nInitSize;
USHORT nGrowSize;
public:
MemoryPool( USHORT nUnitSize,
USHORT nInitSize = 1024,
USHORT nGrowSize = 256 );
~MemoryPool();
void* Alloc();
void Free( void* p );
};
MemoryPool.cpp 的實(shí)現(xiàn)
#include "MemoryPool.h"
MemoryPool::MemoryPool( USHORT _nUnitSize,
USHORT _nInitSize, USHORT _nGrowSize )
{
pBlock = NULL;
nInitSize = _nInitSize;
nGrowSize = _nGrowSize;
if ( _nUnitSize > 4 )
nUnitSize = (_nUnitSize + (MEMPOOL_ALIGNMENT-1)) & ~(MEMPOOL_ALIGNMENT-1);
else if ( _nUnitSize <= 2 )
nUnitSize = 2;
else
nUnitSize = 4;
}
void* MemoryPool::Alloc()
{
MemoryBlock* pMyBlock;
if ( !pBlock ){
//第一次調(diào)用初始化內(nèi)存塊
pMyBlock =new(nGrowSize, nUnitSize) MemoryBlock(nGrowSize, nUnitSize);
pBlock = pMyBlock;
return (void*)(pMyBlock->aData);
}
pMyBlock = pBlock;
while (pMyBlock && !pMyBlock->nFree )
pMyBlock = pMyBlock->pNext;
if ( pMyBlock ){
printf("get a mem from block\n");
char* pFree = pMyBlock->aData+(pMyBlock->nFirst*nUnitSize);
//aData記錄實(shí)際的內(nèi)存單元標(biāo)識
pMyBlock->nFirst = *((USHORT*)pFree);
pMyBlock->nFree--;
return (void*)pFree;
}
else{
printf("add a new block\n");
if (!nGrowSize)
return NULL;
pMyBlock = new(nGrowSize, nUnitSize) MemoryBlock(nGrowSize, nUnitSize);
if (!pMyBlock )
return NULL;
pMyBlock->pNext = pBlock;
pBlock = pMyBlock;
return (void*)(pMyBlock->aData);
}
}
void MemoryPool::Free( void* pFree ){
MemoryBlock* pMyBlock = pBlock;
MemoryBlock* preMyBlock;
//確定該待回收分配單元(pFree)落在哪一個(gè)內(nèi)存塊的指針范圍內(nèi),大于起始節(jié)點(diǎn),小于終止節(jié)點(diǎn)。
while ( ((ULONG)pMyBlock->aData > (ULONG)pFree) ||
((ULONG)pFree >= ((ULONG)pMyBlock->aData + pMyBlock->nSize))){
//不在內(nèi)存塊范圍內(nèi),則歷遍下一個(gè)節(jié)點(diǎn)
preMyBlock=pMyBlock;
pMyBlock=pMyBlock->pNext;
}
pMyBlock->nFree++;
*((USHORT*)pFree) = pMyBlock->nFirst;
pMyBlock->nFirst = (USHORT)(((ULONG)pFree-(ULONG)(pBlock->aData)) / nUnitSize);
//判斷內(nèi)存塊是否全部為自由狀態(tài),是則釋放整個(gè)內(nèi)存塊
if (pMyBlock->nFree*nUnitSize == pMyBlock->nSize ){
preMyBlock->pNext=pMyBlock->pNext;
delete pMyBlock;
}
}
MemoryBlock::MemoryBlock (USHORT nTypes, USHORT nUnitSize)
: nSize (nTypes * nUnitSize),
nFree (nTypes - 1),
nFirst (1),
pNext (0)
{
char * pData = aData;
for (USHORT i = 1; i < nTypes; i++) {
//將內(nèi)存塊的前2個(gè)字節(jié)用來存放內(nèi)存單元的標(biāo)識
*reinterpret_cast(pData) = i;
pData += nUnitSize;
}
}
總結(jié)
以上是生活随笔為你收集整理的java构建内存池队列_内存池完整实现代码及一些思考的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 直击部分省份高考结束:考生飞奔 家长送花
- 下一篇: 学安全工程用不用计算机,上重点大学的末流