根据可用内存决定每次申请多大内存

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;
        }
    }

 

posted @ 2018-01-08 14:40  秋月的私语  阅读(343)  评论(0编辑  收藏  举报