#include <windows.h>
struct DEMOStruct
{
BOOL bUsed;
BYTE Buffer[2048 - sizeof(BOOL)];
};
class VMMGR
{
public:
VMMGR(void);
~VMMGR(void);
public:
BOOL InitVMMgr(int nInitSectorCount);
void CloseVMMgr();
BYTE *ApplicationOneSector(void); //申请一个Sector
BYTE *GetBuffPTR(int nIndex); //获取某一个索引对应的指针
void FreeSector(int nIndex); //释放资源
void GabageCollect(void); //回收没有被使用的单元
private:
BYTE *m_pBaseAddr;
int m_nSectorCount;
int m_nCommitCount;
int m_nFreeCount;
int m_nPageSize;
};
VMMGR::VMMGR(void)
:m_pBaseAddr(NULL)
,m_nSectorCount(0)
,m_nCommitCount(0)
,m_nFreeCount(0)
{
}
VMMGR::~VMMGR(void)
{
CloseVMMgr();
}
BOOL VMMGR::InitVMMgr(int nInitSectorCount)
{
CloseVMMgr();
m_pBaseAddr = (BYTE *) VirtualAlloc(NULL, nInitSectorCount * sizeof(DEMOStruct),
MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE);
if(NULL == m_pBaseAddr)
return FALSE;
SYSTEM_INFO si;
GetSystemInfo(&si);
m_nPageSize = si.dwPageSize;
m_nSectorCount = nInitSectorCount;
m_nCommitCount = 0;
m_nFreeCount = 0;
}
void VMMGR::CloseVMMgr()
{
if (!m_pBaseAddr)
{
return;
}
VirtualFree(m_pBaseAddr, 0, MEM_RELEASE);
m_pBaseAddr = NULL;
m_nSectorCount = 0;
m_nCommitCount = 0;
m_nFreeCount = 0;
}
BYTE *VMMGR::ApplicationOneSector(void)
{
BYTE *pBuff = NULL;
do
{
if (!m_pBaseAddr)
break;
if ((0 == m_nFreeCount) && (m_nCommitCount == m_nSectorCount))
break;
if (0 == m_nFreeCount)
{
pBuff = m_pBaseAddr + m_nCommitCount * sizeof(DEMOStruct);
VirtualAlloc(pBuff, sizeof(DEMOStruct),
MEM_COMMIT, PAGE_READWRITE);
((DEMOStruct *)(pBuff))->bUsed = TRUE;
m_nCommitCount++;
break;
}
else if(m_nFreeCount > 0)
{
for (int nIndex = 0; nIndex < m_nCommitCount; nIndex++)
{
pBuff = m_pBaseAddr + nIndex * sizeof(DEMOStruct);
try
{
if (FALSE == ((DEMOStruct *)(pBuff))->bUsed)
{
((DEMOStruct *)(pBuff))->bUsed = TRUE;
m_nFreeCount--;
break;
}
}
catch (...) //被回收了
{
VirtualAlloc(pBuff, sizeof(DEMOStruct),
MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE);
((DEMOStruct *)(pBuff))->bUsed = TRUE;
m_nFreeCount--;
break;
}
}
}
} while (0);
return pBuff;
}
BYTE *VMMGR::GetBuffPTR(int nIndex)
{
BYTE *pBuff = NULL;
do
{
if (!m_pBaseAddr)
break;
if(nIndex + 1 >= m_nCommitCount)
break;
BYTE *pBuff = m_pBaseAddr + nIndex * sizeof(DEMOStruct);
try
{
if (FALSE == ((DEMOStruct *) (pBuff))->bUsed)
{
pBuff = NULL;
break;
}
}
catch (...)
{
printf("this area %p have release/r/n", pBuff);
pBuff = NULL;
break;
}
} while (0);
return pBuff;
}
void VMMGR::FreeSector(int nIndex) //释放资源
{
do
{
if (!m_pBaseAddr)
break;
if(nIndex + 1 >= m_nCommitCount)
break;
BYTE *pBuff = m_pBaseAddr + nIndex * sizeof(DEMOStruct);
try
{
if (TRUE == ((DEMOStruct *) (pBuff))->bUsed)
{
((DEMOStruct *) (pBuff))->bUsed = FALSE;
m_nFreeCount++;
}
}
catch (...)
{
printf("this area %p have release/r/n", pBuff);
break;
}
} while(0);
}
void VMMGR::GabageCollect(void)
{
do
{
if (!m_pBaseAddr)
{
break;
}
if (0 == m_nCommitCount)
{
break;
}
int nPageCount = m_nCommitCount * sizeof(DEMOStruct) / m_nPageSize;
for (int nPageIndex = 0; nPageIndex < nPageCount; nPageIndex++)
{
int nIndexFirst = nPageIndex * m_nPageSize / sizeof(DEMOStruct);
int nIndexLast = nIndexFirst + m_nPageSize / sizeof(DEMOStruct);
BOOL bFree = TRUE;
for (int nIndex = nIndexFirst; nIndex < nIndexLast; nIndex++)
{
BYTE *pBuf = m_pBaseAddr + nIndex * sizeof(DEMOStruct);
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(pBuf, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
if ((mbi.State == MEM_RESERVE) || ((mbi.State == MEM_COMMIT)
&& (TRUE == ((DEMOStruct *)(pBuf))->bUsed)))
{
bFree = FALSE;
break;
}
}
if (bFree)
{
BYTE *pBuf = m_pBaseAddr + nIndexFirst * sizeof(DEMOStruct);
VirtualFree(pBuf, sizeof(DEMOStruct), MEM_DECOMMIT);
}
}
} while(0);
}
int _tmain(int argc, _TCHAR* argv[])
{
VMMGR testVMMGR;
testVMMGR.InitVMMgr(100);
for (int i = 0; i < 20; i++)
{
testVMMGR.ApplicationOneSector();
}
for (int i = 0; i < 10; i++)
{
testVMMGR.FreeSector(i);
}
testVMMGR.GabageCollect();
for (int i = 0; i < 20; i++)
{
testVMMGR.ApplicationOneSector();
}
testVMMGR.CloseVMMgr();
getchar();
return 0;
}