根据可用内存决定每次申请多大内存
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; } }