日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java构建内存池队列_内存池完整实现代码及一些思考

發布時間:2023/12/10 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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构建内存池队列_内存池完整实现代码及一些思考的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。