linux下进程的栈大小有限制吗
Linux 中进程的堆栈大小有限制吗?它仅仅取决于机器的 RAM 吗?
我想知道这一点,以便限制函数递归调用的深度。
Is there a limit on the stack size of a process in Linux? Is it simply dependent on the RAM of the machine?
I want to know this in order to limit the depth of recursive calls to a function.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
堆栈通常受到资源限制。您可以使用
ulimit -a
查看安装的默认设置:(这表明我的设置是 8MB,很大)。
如果删除或增加该限制,您仍然无法将计算机中的所有 RAM 用于堆栈 - 堆栈从靠近进程地址空间顶部的点向下增长,并且在某个时刻它将运行到您的代码、堆或加载的库中。
The stack is normally limited by a resource limit. You can see what the default settings are on your installation using
ulimit -a
:(this shows that mine is 8MB, which is huge).
If you remove or increase that limit, you still won't be able to use all the RAM in the machine for the stack - the stack grows downward from a point near the top of your process's address space, and at some point it will run into your code, heap or loaded libraries.
该限制可由管理员设置。
请参阅man ulimit。
可能有一个你无法跨越的默认值。如果您必须担心堆栈限制,我想说您需要重新考虑您的设计,也许编写一个迭代版本?
The limit can be set by the admin.
See man ulimit.
There is probably a default which you cannot cross. If you have to worry about stack limits, I would say you need to rethink your design, perhaps write an iterative version?
这很大程度上取决于您所使用的体系结构(32 位或 64 位)以及您是否是多线程的。
默认情况下,在单线程进程中,即操作系统在 exec() 时创建的主线程中,堆栈通常会增长,直到它遇到地址空间中的其他内容。这意味着在 32 位机器上通常可以拥有 1G 的堆栈。
然而,在多线程 32 位进程中绝对不是这种情况。在多线程进程中,堆栈共享地址空间,因此需要进行分配,因此通常会给予它们少量的地址空间(例如1M),以便可以在不耗尽地址空间的情况下创建许多线程。
因此,在多线程进程中,它很小且有限,在单线程进程中,基本上直到您遇到地址空间中的其他内容(默认分配机制试图确保不会太快发生)。
在 64 位机器中,当然有更多的地址空间可供使用。
在任何情况下,你总是可能会耗尽虚拟内存,在这种情况下你会得到一个 SIGBUS 或 SIGSEGV 或其他东西。
It largely depends what architecture you're on (32 or 64-bit) and whether you're multithreaded or not.
By default in a single threaded process, i.e. the main thread created by the OS at exec() time, your stack usually will grow until it hits something else in the address space. This means that it is generally possible, on a 32-bit machine, to have, say 1G of stack.
However, this is definitely NOT the case in a multithreaded 32-bit process. In multithreaded procesess, the stacks share address space and hence need to be allocated, so they typically get given a small amount of address space (e.g. 1M) so that many threads can be created without exhausting address space.
So in a multithreaded process, it's small and finite, in a single threaded one, it's basically until you hit something else in the address-space (which the default allocation mechanism tries to ensure doesn't happen too soon).
In a 64-bit machine, of course there is a lot more address space to play with.
In any case you can always run out of virtual memory, in which case you'll get a SIGBUS or SIGSEGV or something.
会对已接受的答案发表评论,但显然我需要更多代表......
真正的堆栈溢出可能很微妙,并不总是会导致任何错误消息或警告。我刚刚遇到过一种情况,唯一的症状是套接字连接会因奇怪的 SSL 错误而失败。其他一切都很好。线程可以进行 malloc()、获取锁、与数据库对话等。但是新连接会在 SSL 层失败。
通过 GnuTLS 中的堆栈跟踪,我对真正的原因感到非常困惑。在花了很多时间试图弄清楚之后,几乎将这些痕迹报告给了他们的团队。
最终发现堆栈大小设置为 8Mb,并且在提高它后问题立即消失了。将堆栈降低到 8Mb 又会导致问题出现 (ABA)。
因此,如果您正在排除似乎奇怪的套接字错误,而没有任何其他警告或未初始化的内存错误......它可能是堆栈溢出。
Would have commented on the accepted answer but apparently I need more rep....
True Stack Overflow can be subtle and not always cause any error messages or warnings. I just had a situation where the only symptom was that socket connections would fail with strange SSL errors. Everything else worked fine. Threads could malloc(), grab locks, talk to the DB, etc. But new connections would fail at the SSL layer.
With stack traces from well within GnuTLS I was quite confused about the true cause. Nearly reported the traces to their team after spending lots of time trying to figure it out.
Eventually found that the stacksize was set to 8Mb and immediately upon raising it the problems vanished. Lowering the stack back to 8Mb brought the problem back (ABA).
So if you are troubleshooting what appears to be strange socket errors without any other warnings or uninitialized memory errors.... it could be stack overflow.