首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

线程空间不足没法创建,内存却是充足的

2013-07-21 
线程空间不足无法创建,内存却是充足的主线程创建3000个子线程,每个线程运行一小段代码后关闭。并行时最多90

线程空间不足无法创建,内存却是充足的
主线程创建3000个子线程,每个线程运行一小段代码后关闭。并行时最多900个线程,运行没有错误。图如下:
线程空间不足没法创建,内存却是充足的
然后,改为主线程创建10个子线程,10个子线程再分别创建3000个子线程,运行一小段代码后关闭。并行到1400个线程时报错,getlasterror返回8,内存空间不足,无法创建。图如下:
线程空间不足没法创建,内存却是充足的
线程空间不足没法创建,内存却是充足的
第二种情况与第一种情况差不了多少啊,内存都是充足的,为什么会报错呢?是不是操作系统会设定最大的栈空间限制而不单单看所剩内存呢? 线程堆栈 内存 操作系统 栈 多线程
[解决办法]
内存用的虽然少,但预留的多,每个线程都要为线程预留栈空间,所以内存虽然没用,但已经被线程“预订”了。
vc生成的pe文件默认每个线程保留栈大小是1M,所以1400个线程,就相当于“预订”了1400M空间,而32位地址空间只有不到2G,所以提示没有内存是合理的,因为确实没有更多的内存做新创建的线程的栈了。
[解决办法]
摘自MSDN:
Each new thread or fiber receives its own stack space consisting of both reserved and initially committed memory. The reserved memory size represents the total stack allocation in virtual memory. As such, the reserved size is limited to the virtual address range. The initially committed pages do not utilize physical memory until they are referenced; however, they do remove pages from the system total commit limit, which is the size of the page file plus the size of the physical memory. The system commits additional pages from the reserved stack memory as they are needed, until either the stack reaches the reserved size minus one page (which is used as a guard page to prevent stack overflow) or the system is so low on memory that the operation fails.

It is best to choose as small a stack size as possible and commit the stack that is needed for the thread or fiber to run reliably. Every page that is reserved for the stack cannot be used for any other purpose.



A stack is freed when its thread exits. It is not freed if the thread is terminated by another thread.


The default size for the reserved and initially committed stack memory is specified in the executable file header. Thread or fiber creation fails if there is not enough memory to reserve or commit the number of bytes requested. To specify a different default stack size for all threads and fibers, use the STACKSIZE statement in the module definition (.def) file. For more information on these default sizes and how to change them, see the documentation included with your linker.

To change the initially committed stack space, use the dwStackSize parameter of the CreateThread, CreateRemoteThread, or CreateFiber function. This value is rounded up to the nearest page. Generally, the reserve size is the default reserve size specified in the executable header. However, if the initially committed size specified by dwStackSize is larger than the default reserve size, the reserve size is this new commit size rounded up to the nearest multiple of 1 MB. 

To change the reserved stack size, set the dwCreationFlags parameter of CreateThread or CreateRemoteThread to STACK_SIZE_PARAM_IS_A_RESERVATION and use the dwStackSize parameter. In this case, the initially committed size is the default size specified in the executable header. For fibers, use the dwStackReserveSize parameter of CreateFiberEx. The committed size is specified in the dwStackCommitSize parameter.

The SetThreadStackGuarantee function sets the minimum size of the stack associated with the calling thread or fiber that will be available during any stack overflow exceptions.


虚拟空间已经分配出去了,但如果这个空间没有被使用,不占用实际的物理内存,所以楼主创建的线程已经没有虚拟空间可以使用了,但每个线程实际使用的堆栈空间并不多,所以显示物理内存足够,但线程创建失败。楼主如果设置合适的线程栈空间,还可以创建更多的线程。

热点排行