使用AfxBeginThread启动一个新的线程,没有指定stack size(应该就是继承主线程的设置吧),在新的线程中申请500M左右的内存(CriticalSection已设置),无论是堆栈还是虚拟内存都申请失败,申请代码如下:
虚拟内存方式:
LPVOID memStore = ::VirtualAlloc(NULL , 5600*5600*16 , MEM_COMMIT , PAGE_READWRITE);
或堆栈方式:
LPVOID memStore = ::HeapAlloc(GetProcessHeap() , 0, 5600*5600*16);
这两种方式都无法申请500M内存。放到主线程中申请这么大空间就没有任何问题。请教一下各位有没有类似问题的经历?
虚拟内存方式:
LPVOID memStore = ::VirtualAlloc(NULL , 5600*5600*16 , MEM_COMMIT , PAGE_READWRITE);
或堆栈方式:
LPVOID memStore = ::HeapAlloc(GetProcessHeap() , 0, 5600*5600*16);
这两种方式都无法申请500M内存。放到主线程中申请这么大空间就没有任何问题。请教一下各位有没有类似问题的经历?
{
LPVOID memStore = ::VirtualAlloc(NULL , 5600*5600*16 , MEM_COMMIT , PAGE_READWRITE);
if(memStore == NULL)
{
DWORD err = ::GetLastError();
}else
{
::VirtualFree(memStore, 0, MEM_RELEASE);
}
return 0;
}
1、分页文件大小不足,这种情况创建一个文件然后用CreateFileMapping可以解决。
2、虚拟地址空间不足,这种情况最好把是减小要分配的内存块,并应尽早分配内存(例如在程序刚开始执行时分配)。
coooooooool,内存映射文件居然申请成功,谢谢楼上两位BTW, 内存映射文件方式下读写的性能如何?比起其他两种内存操作方式怎么样?
新的代码如下:
HANDLE hFile = CreateFile("d:\\data.dat", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
HANDLE hDLHSMap = ::CreateFileMapping(hFile , NULL , PAGE_READWRITE ,
0 , 500000000 , "DLHS");
double *pDLHS = (double*)::MapViewOfFile(hDLHSMap , FILE_MAP_READ|FILE_MAP_WRITE , 0 , 0 , 0);在新的线程中运行后发现指针pDLHS就是NULL。而放在主线程就工作正常。我在新线程中执行一套算法,需要申请不少内存,但500M这个是最大的一块,一直没法申请成功。究竟主线程和新的WORKER THREAD在申请内存方面有什么区别呵?
谢谢。但新的线程中并不是每次都要开这么大的内存,用户不是每次都要执行这段算法有没有什么方法正面解决WORKER THREAD中不能开辟大内存的问题。
进程的前2GB地址空间是用户模式下使用的。在程序运行过程中,创建线程、LoadLibrary、MapViewOfFile、分配大块内存等可能会把未使用的地址空间分割成若干小块空间,使得最大连续地址空间变小。所以我才建议你“在程序刚开始执行时分配,将指针保存为全局变量”。你先分配好内存只是把这个地址空间占用,当你不使用它时是不需要占用物理内存的,也不需要占用运行时间,唯一的影响是要占用系统分页文件的空间(只是占用)。如果不想占用系统分页文件的空间可以用FileMapping。