java构建内存池队列_内存池完整实现代码及一些思考
為了提高效率和有效的監控內存的實時狀態,我們采取了內存池的思想來解決效率與對內存實現監控的問題。
網上查找到了一些方案,根據自己的理解實現了應用。
我們什么時候要調用到內存池,
1,當我們頻繁的申請釋放同樣數據大小的內存空間,我們可以用比動態new更有效方式來管理內存時,我們應該用內存池來提高效率。
2,當我們需要知道內存實時的申請狀態,以便于對于服務器內存狀態做實時預警時,我們可以用內存池的接口,來給內存增加監控。
實現的特點:
1,內存池內存單元大小可以動態定義,實現多級內存池。
2,申請效率很高,單元測試下是普通new/delete的4倍左右,當然具體性能還應機器類別而異。
MemoryPool.h 的實現
//該內存池理論來自于IBM文章,http://www.ibm.com/developerworks/cn/linux/l-cn-ppp/index6.html
//作者馮宏華,徐瑩,程遠,汪磊享有論文著作權,由2011-06-06 konyel lin根據相關代碼和理論進行優化修改。
#include
#include
//內存對齊值,可以根據機器取指長度進行設置
#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 的實現
#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 ){
//第一次調用初始化內存塊
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記錄實際的內存單元標識
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)落在哪一個內存塊的指針范圍內,大于起始節點,小于終止節點。
while ( ((ULONG)pMyBlock->aData > (ULONG)pFree) ||
((ULONG)pFree >= ((ULONG)pMyBlock->aData + pMyBlock->nSize))){
//不在內存塊范圍內,則歷遍下一個節點
preMyBlock=pMyBlock;
pMyBlock=pMyBlock->pNext;
}
pMyBlock->nFree++;
*((USHORT*)pFree) = pMyBlock->nFirst;
pMyBlock->nFirst = (USHORT)(((ULONG)pFree-(ULONG)(pBlock->aData)) / nUnitSize);
//判斷內存塊是否全部為自由狀態,是則釋放整個內存塊
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++) {
//將內存塊的前2個字節用來存放內存單元的標識
*reinterpret_cast(pData) = i;
pData += nUnitSize;
}
}
總結
以上是生活随笔為你收集整理的java构建内存池队列_内存池完整实现代码及一些思考的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 直击部分省份高考结束:考生飞奔 家长送花
- 下一篇: 学安全工程用不用计算机,上重点大学的末流