DWORD GetPropMemSizeOneTime()
{
DWORD MB = 1024*1024;
DWORD GB = 1024 * MB;
//最大一次申请1GB
DWORD dwPropOneTime = GB;
//获取可用内存的80%作为缓存
MEMORYSTATUS stat;
GlobalMemoryStatus(&stat);
SIZE_T dCurMemAvail = SIZE_T(stat.dwAvailPhys * 0.8);
if (dCurMemAvail > 32 * GB)
{
dwPropOneTime = GB;
}
else if (dCurMemAvail > 16 * GB)
{
dwPropOneTime = 512 * MB;
}
else if (dCurMemAvail > 8 * GB)
{
dwPropOneTime = 256 * MB;
}
else if (dCurMemAvail > 4 * GB)
{
dwPropOneTime = 128 * MB;
}
else if (dCurMemAvail > 2 * GB)
{
dwPropOneTime = 64 * MB;
}
else
{
//最小一次申请16MB
dwPropOneTime = 16 * MB;
}
return dwPropOneTime;
}
//获取可用内存的80%作为缓存
MEMORYSTATUS stat;
GlobalMemoryStatus(&stat);
SIZE_T dCurMemAvail = SIZE_T(stat.dwAvailPhys * 0.8);
int nBandNumNeed = nBandNum != 0 ? nBandNum : 1;
int nBlockSize = int(dCurMemAvail / nCols / nBandNumNeed);
//如果块大小超过dwPropOnetime,则取较小的值dwPropOnetime
INT64 nMemNeed = (INT64)nBlockSize * nCols * nBandNumNeed;
DWORD dwPropOnetime = GetPropMemSizeOneTime();
nMemNeed = nMemNeed > dwPropOnetime ? dwPropOnetime : nMemNeed;
//内存对齐
nMemNeed = (nMemNeed / 512 + 1) * 512;
nBlockSize = int(nMemNeed / nCols / nBandNumNeed);
nBlockSize = nRows < nBlockSize ? nRows : nBlockSize;
const int nBPP = nBPB * nBandNumNeed;
if (nBlockSize == 0)
{
//可用内存太少,影像的一行都无法正常读取
return FALSE;
}
INT64 nAllocateMem = (INT64)nBlockSize*nCols*nBandNumNeed / 1024 /1024; //MB,调试用
//allocate mem
int nMemBlock = int(dCurMemAvail / (nBlockSize*nCols*nBandNumNeed));
int nNeedMemBlockNum = nRows % nBlockSize == 0 ? nRows / nBlockSize : nRows / nBlockSize + 1;;
nMemBlock = nNeedMemBlockNum < nMemBlock ? nNeedMemBlockNum : nMemBlock;
if (nMemBlock == 0)
{
//可用内存太少,影像的一行都无法正常读取
return FALSE;
}
int nRowBlockNum = nMemBlock;
int nBlock = nBlockSize;
BYTE** pBlockBufferRead = new BYTE*[nRowBlockNum];
for (int j = 0; j < nRowBlockNum; ++j)
{
try
{
pBlockBufferRead[j] = new BYTE[nCols * nBandNum * nBPB * nBlock];
memset(pBlockBufferRead[j], 0, sizeof(BYTE)* nCols * nBandNum * nBPB * nBlock);
}
catch ( const std::bad_alloc& e )
{
//释放j之前已经分配的内存,并且将当前的指针赋值为nullptr
for (int k = 0; k < nRowBlockNum; ++k)
{
delete[] pBlockBufferRead[k];
pBlockBufferRead[k] = nullptr;
}
pBlockBufferRead[j] = nullptr;
return false;
}
}