/stack开关设置问题

xiewneqi 2009-10-12 11:50:22
最近在看《windows via c/c++》,里面关于线程的论述有一段话“The reserve amount sets an upper limit for the stack so that you can catch endless recursion bugs in your code”,我理解为/STACK:reserve指定的值将做为线程堆栈大小的上限,若超出则引发stack overflow异常。自己写了一个程序测试,在main中开了一个10240大小的int数组,然后将/STACK:reverse开关值设置为1024,调试,没报错,知道自己理解错了,在此向各位请教/STACK开关和上面那句话的意义。非常不好意思只有20可用分,不过这也是全部家当了,大家就不要嫌弃,来帮帮我吧 :)
...全文
306 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiewneqi 2009-10-13
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 jackyjkchen 的回复:]
Windows默认栈最小1M吧……
[/Quote]
这个有出处没?网上查不到,只查到在指定/STACK:reverse为0时其默认大小为1MB(MSDN)。而且,就算是最小为1MB,当我把保持/STACK:reverse为1024,并将数组开到int p[102400]时,就会发生stack overflow错误,数组p此时大小也只是400K啊,最后,如果将/STACK:reverse复位为0,使用默认的1MB,开400k的数组就不会出错了。这也能说明默认栈大小最小并不是1MB。
jackyjkchen 2009-10-13
  • 打赏
  • 举报
回复
Windows默认栈最小1M吧……
xiewneqi 2009-10-13
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 yodoyodo 的回复:]
按照默认设置,系统保留1 MB的地址空间并提交两个页面的内存。但是,这些默认值是可以修改的,方法是在你链接应用程序时设定M i c r o s o f t的链接程序的/ S TA C K选项:


/STACK:reserve[,commit]
当创建一个线程的堆栈时,系统将会保留一个链接程序的/ S TA C K开关指明的地址空间区域。但是,当调用C r e a t e T h r e a d或_ b e g i n t h r e a d e x函数时,可以重载原先提交的内存数量。这两个函数都有一个参数,可以用来重载原先提交给堆栈的地址空间的内存数量。如果设定这个参数为0,那么系统将使用/ S TA C K开关指明的已提交的堆栈大小值。

---- <windows核心编程>
[/Quote]
哥们,你看我问题了么.....
YODOYODO 2009-10-13
  • 打赏
  • 举报
回复
按照默认设置,系统保留1 MB的地址空间并提交两个页面的内存。但是,这些默认值是可以修改的,方法是在你链接应用程序时设定M i c r o s o f t的链接程序的/ S TA C K选项:


/STACK:reserve[,commit]
当创建一个线程的堆栈时,系统将会保留一个链接程序的/ S TA C K开关指明的地址空间区域。但是,当调用C r e a t e T h r e a d或_ b e g i n t h r e a d e x函数时,可以重载原先提交的内存数量。这两个函数都有一个参数,可以用来重载原先提交给堆栈的地址空间的内存数量。如果设定这个参数为0,那么系统将使用/ S TA C K开关指明的已提交的堆栈大小值。

----<windows核心编程>
xiewneqi 2009-10-13
  • 打赏
  • 举报
回复
结贴,问题已经查清楚了。下面的内容转自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. The default stack reservation size used by the linker is 1 MB. To specify a different default stack reservation size for all threads and fibers, use the STACKSIZE statement in the module definition (.def) file. The operating system rounds up the specified size to the nearest multiple of the system's allocation granularity (typically 64 KB). To retrieve the allocation granularity of the current system, use the GetSystemInfo function.

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 or equal to 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.

大概意思:线程栈空间默认是1M,手动配置该值时(通过/STACK开关或者def文件的STACK指令),系统实际分配的栈大小是该值向上舍入到最近的整数倍栈粒度(一般是64K,可调用GetSystemInfo查询)大小,比如在/STACK中手动配置值为65K,系统则会分配128K(=2 * 64K)的栈空间。
CreateThread函数中的dwStackSize参数并不是为新线程指定的栈空间大小,它是初次提交给线程栈空间的页面大小,系统实际提交的大小是该值向上舍入到最近的页面文件大小整数倍大小,比如指定dwStackSize为13K时,由于页面文件一般为4K,因此系统将实际提交4*4 = 16K的页面文件。
如果dwStackSize大于/STACK的指定值或默认值1M,系统将调整线程栈大小,使其变为dwStackSize向上舍入且距离dwStackSize最近的1M的整数倍。比如dwStackSize设置为2049K,且/STACK保持默认值1M,则系统将线程栈空间调整为3M。
an_bachelor 2009-10-13
  • 打赏
  • 举报
回复
貌似他栈空间会自动增长的 准确地我也说不上 好像是希望翻译的那几本VC的书(实际上就是翻译部分msdn) 有一卷讲编译器、优化讲到这个
jackyjkchen 2009-10-13
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 xiewneqi 的回复:]
引用 1 楼 jackyjkchen 的回复:
Windows默认栈最小1M吧……

这个有出处没?网上查不到,只查到在指定/STACK:reverse为0时其默认大小为1MB(MSDN)。而且,就算是最小为1MB,当我把保持/STACK:reverse为1024,并将数组开到int p[102400]时,就会发生stack overflow错误,数组p此时大小也只是400K啊,最后,如果将/STACK:reverse复位为0,使用默认的1MB,开400k的数组就不会出错了。这也能说明默认栈大小最小并不是1MB。
[/Quote]
这样试试,1M是一个默认点,还有一个点是64K,你试试64k左右的数组,看是不是默认64K

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧