某个程序的堆栈内存有多大,是否有编译器标志可以设置它?

14
如标题所述:关于堆栈大小是否有任何通用的“经验法则”?我猜大小会因操作系统、架构、高速缓存大小、可用内存等而异。
但是,能否就一般情况下堆栈允许使用多少提供任何信息,或者是否有任何方式可以找到这个程序允许使用的堆栈量?额外的问题是,是否有任何方法(使用编译器标志等(在这里主要思考C/C ++,但还包括更普遍的))可以由用户将堆栈大小设置为固定大小?
顺便说一句,我纯粹出于好奇心而问,我没有堆栈溢出的问题。 :)

1
一个给定程序将使用的堆栈数量通常是不可判定的(它等同于停机问题)。您是否在询问如何显式强制限制堆栈大小? - Oliver Charlesworth
@Anders:您的程序可以使用的堆栈大小是非常明确定义的。任何程序需要正确运行的堆栈量类似于该程序的“停机问题”(在一般情况下只是不可判定的——大多数具体的程序允许分析)。 - Ben Voigt
@JimBalter:我使用这些作为示例,说明代码库何时可能从“显然可以静态分析”转变为“哦,是的,那将是棘手的分析”(作为“不可能”的手摆先驱)。 - Oliver Charlesworth
@JimBalter:然而,这绝对不是我的领域,所以如果你说可以确定有界存储程序是否停止,我会选择相信你 ;) - Oliver Charlesworth
@Oli 有限的内存意味着有限数量的状态。对于给定的程序,每个状态都可以映射到下一个连续的状态。然后,对于任何起始状态,您(也就是图灵机,它不受寿命甚至宇宙持续时间的限制)都可以确定它是否达到停止状态或者它是循环的一部分。 - Jim Balter
显示剩余9条评论
2个回答

6

1
实际上,如果你向CreateThread函数传递0,那么默认的线程大小就与启动线程的堆栈大小(如PE头中指定的那样)相同。 - Ben Voigt
@BenVoigt:我之前不知道这个,但是现在听起来很有道理。谢谢! - Eric Lippert
只是额外的信息:创建本地线程的API(允许指定堆栈大小)是CreateThread - Ben Voigt

5

1
没有选择。在Unix系统上,初始线程的最大堆栈大小由ulimit命令/setrlimit函数确定,但在Linux上,保留/已提交堆栈大小固定为大约128k加一点额外的空间,这似乎取决于环境(典型的总量为132k或136k)。如果程序试图将堆栈增长超过此大小,并且有可用内存,它可以增长到ulimit/setrlimit设置的限制,但是在exec发生时无法保留超过 ~128k 以上的内存。 - R.. GitHub STOP HELPING ICE
我通常假设 overcommit 已禁用。启用 overcommit 将导致系统出现可怕的漏洞、不符合规范和危险不稳定。 :-)无论如何,即使启用了 overcommit,尝试扩大堆栈可能会触发 OOM killer 杀死您的进程。 - R.. GitHub STOP HELPING ICE
@R..:现代系统更有可能出现虚拟地址空间碎片问题,而不是交换空间耗尽的问题。如果你不喜欢过度承诺的话,你应该向内核开发人员提出来。 - Ben Voigt
栈的增长通常不会受到地址空间碎片化的限制;内核保留了一个虚拟地址范围,大小等于RLIMIT_STACK,最多可增长至至少8 MB左右的合理限制。它只是不保留提交费用。 - R.. GitHub STOP HELPING ICE
@R..:你上面的评论让“保留”和“提交”变得混乱,因为你之前说过只有 ~132k 被保留。 - Ben Voigt
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接