在DLL中执行,当文件较大(>408MB)就报ERROR_NOT_ENOUGH_MEMORY错!在测试程序(非DLL)中执行就没有问题!
程序线程比较多,20多个,有影响吗?

解决方案 »

  1.   

    “程序线程比较多?”
    你的意思是20多个都在多文件映射,如果是的话,则可能是虚拟地址空间不够(>20*408M),一个程序的地址空间<2G
      

  2.   

    进程管理器里显示只用了60MB内存,系统还有5,600MB可用,应该不是内存的问题。20多个线程是整个程序一起用了这么多,都各自有自己的任务。文件映射这个DLL模块只有2个线程。经反复测试发现数据库连接建立后执行就不能成功,而不连接数据库一定能成功。和内存,线程的确没有关系。
    数据库连接用的ADO,测试代码加在连接函数前成功,在连接函数后失败。
    不知道ADO内部做了什么操作,有没有人遇到同样的问题啊?连接函数基本上就是下面的代码:
    //初始化COM
        if ( FAILED(::CoInitialize(NULL)) )
            return FALSE;    try
    {   
    //连接数据库字符串
    _bstr_t bstrConnect(lpszConnectString);
    _bstr_t bstrEmpty;

    m_Conn.CreateInstance(__uuidof( ADODB::Connection)); m_Conn->CursorLocation      = ADODB::adUseClient;
    m_Conn->CommandTimeout      = 0;
    m_Conn->ConnectionTimeout   = 10;
    m_Conn->ConnectionString    = bstrConnect;

            HRESULT res = m_Conn->Open( bstrConnect, bstrEmpty, bstrEmpty, -1 );
            if ( FAILED(res))
                return FALSE;        m_bConnected = TRUE;
    }
    catch(_com_error &e)
    {
    ShowError(e);
    return FALSE;
    }
      

  3.   

    映射文件要求连续地址空间,即使空闲内存很多,也常常难以满足。这里是一段代码,错误处理不太严格
    void FileMappingCopy(TCHAR* Src, TCHAR* Tgt){
    HANDLE hSrcFile = CreateFile(Src, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL);
    HANDLE hDstFile = CreateFile(Tgt, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if( hSrcFile == INVALID_HANDLE_VALUE || hDstFile == INVALID_HANDLE_VALUE){
    return;
    } DWORD dwRemainSize = GetFileSize(hSrcFile, NULL);
    DWORD dwFileSize = dwRemainSize; HANDLE hSrcFileMapping = CreateFileMapping(hSrcFile, NULL, PAGE_READWRITE, 0, dwRemainSize, NULL);
    HANDLE hDstFileMapping = CreateFileMapping(hDstFile, NULL, PAGE_READWRITE, 0, dwRemainSize, NULL); if( hSrcFileMapping == INVALID_HANDLE_VALUE || hDstFileMapping == INVALID_HANDLE_VALUE){
    return;
    } const int BUFFERBLOCKSIZE = 65536;
    while(dwRemainSize > 0){
    DWORD dwBlock = min(dwRemainSize, BUFFERBLOCKSIZE); LPVOID pSrc = MapViewOfFile(hSrcFileMapping, FILE_MAP_ALL_ACCESS, 0, dwFileSize - dwRemainSize, dwBlock);
    LPVOID pDst = MapViewOfFile(hDstFileMapping, FILE_MAP_ALL_ACCESS, 0, dwFileSize - dwRemainSize, dwBlock); if( pSrc == NULL || pDst == NULL)
    {
    printf("fail\n");
    return;
    } memcpy(pDst, pSrc, dwBlock); UnmapViewOfFile(pSrc);
    UnmapViewOfFile(pDst); dwRemainSize -= dwBlock; }
    CloseHandle(hSrcFileMapping);
    CloseHandle(hDstFileMapping); CloseHandle(hSrcFile);
    CloseHandle(hDstFile);}如果严格来说要用VirtualQuery查询,不过我没研究过