Linux 32位计算机上程序的堆栈分配限制

时间:2009-11-22 18:38:51

标签: c++ compiler-construction

在C ++中,在编译器放弃之前,堆栈段可以增长多少,并说它不能为堆栈分配更多内存。

在linux(fedora)32位计算机上使用gcc。

3 个答案:

答案 0 :(得分:10)

在UNIX下,如果您正在运行bash run

$ ulimit -a

它将列出各种限制,包括堆栈大小。我的是8192kb。您可以使用ulimit更改限制。

此外,您可以使用ulimit()函数在程序中设置各种限制。

$ man 3 ulimit

在Windows下,请参阅StackReserveSizeStackCommitSize

实际上,堆栈地址从高地址开始(在32位平台上,接近3GB限制),在内存分配从低地址开始时减少。这允许堆栈和内存增长,直到整个内存耗尽。

答案 1 :(得分:2)

在我的32位linux上,它的8192K字节。所以它在您的机器上相同。

$ uname -a
Linux TomsterInc 2.6.28-14-generic #46-Ubuntu SMP Wed Jul 8 07:21:34 UTC 2009 i686 GNU/Linux
$ ulimit -s
8192

答案 2 :(得分:1)

Windows(我认为Linux)都在大堆栈模型假设上运行,也就是说,在线程启动之前,有一个堆栈(每个线程)的空间被预先分配。 我怀疑操作系统只是将预分配大小的虚拟内存空间分配给该堆栈区域,并在堆栈末尾超出页面边界时添加实际内存页面,直到达到上限(“ulimit”)为止。 / p>

由于操作系统通常将堆栈放置在远离其他结构的位置,因此当达到ulimit时,操作系统可能能够扩展堆栈,如果发生溢出,则堆栈旁边不会显示任何其他内容。一般来说,如果你正在构建一个足够复杂的程序来溢出堆栈,你可能会动态地分配内存,并且没有任何关于堆栈旁边区域没有被分配的保证。如果分配了这样的内存,那么操作系统当然无法扩展堆栈。

这意味着应用程序不能指望操作系统自动扩展堆栈。实际上,堆栈无法增长。

理论上,耗尽其堆栈的应用程序可能能够启动具有更大堆栈的新线程,复制现有堆栈并继续,但实际上我怀疑这可以做到,如果没有其他原因而不是指针局部变量堆栈需要调整,C / C ++编译器不能找到这样的指针并调整它们。 结果:ulimit必须在程序启动之前声明,一旦超过,程序就会死亡。

如果想要一个可以任意扩展的堆栈,最好切换到使用堆分配激活记录的语言。然后,在地址空间用完之前,您就不会用完。 32或64位VM空间确保您可以使用此技术进行大量递归。

我们有一个名为PARLANSE的并行编程语言,它可以进行堆分配,以便能够以这种方式任意递归数千个并行计算粒度。