内存影射文件时MapViewOfFile 失败,GetLastError返回8 ERROR_NOT_ENOUGH_MEMORY应该怎么解决? 在DLL中执行,当文件较大(>408MB)就报ERROR_NOT_ENOUGH_MEMORY错!在测试程序(非DLL)中执行就没有问题!程序线程比较多,20多个,有影响吗? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 “程序线程比较多?”你的意思是20多个都在多文件映射,如果是的话,则可能是虚拟地址空间不够(>20*408M),一个程序的地址空间<2G 进程管理器里显示只用了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; } 映射文件要求连续地址空间,即使空闲内存很多,也常常难以满足。这里是一段代码,错误处理不太严格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查询,不过我没研究过 这个程序里有几个消费者,几个生产者?? 求教SetDIBitsToDevice函数 Invoke函数出错了 什么是swf sdk 如何拦截自定义消息 m_wndToolBar.SetButtonText(..)为何不好用? 有劳各位,我想要费尔防火墙的源代码第二版,必有重谢! 急急急!关于BW500-PID输出,暂给250 怎样得到别一个process的窗体的HWND啊?? 高手,我想和你切磋一下? 关于DirectX的页面(DirectDrawSurface)的问题 帮忙看是什么问题吧!!
你的意思是20多个都在多文件映射,如果是的话,则可能是虚拟地址空间不够(>20*408M),一个程序的地址空间<2G
数据库连接用的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;
}
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查询,不过我没研究过