为什么大多数操作系统在运行时不能增加堆栈?

How come the stack cannot be increased during runtime in most operating system?

是为了避免碎片化?还是别的什么原因?与具有手动生命周期的 malloc() 相比,内存分配的设置生命周期是一个非常有用的结构。

用于堆栈的space在程序执行过程中随着函数的调用而频繁增加和减少return。堆栈允许的 最大值 space 通常是固定限制。

在旧计算机中,内存是一种非常有限的资源,它可能仍然存在于小型设备中。在这些情况下,硬件功能可能会对最大堆栈大小施加必要的限制。

在具有大量内存的现代系统中,堆栈可能有大量可用,但允许的最大值通常设置为较低的值。这提供了一种捕获“运行away”程序的方法。通常,控制程序使用多少堆栈 space 是软件工程中被忽视的部分。根据实际经验设置了限制,但我们可以做得更好。1

从理论上讲,可以给一个程序一个小的初始限制,如果它发现自己正在处理一个“大”问题,它可以告诉操作系统它打算使用更多。这仍然会捕捉到大多数“运行离开”程序,同时允许精心设计的程序使用更多 space。然而,总的来说,我们设计的程序使用堆栈来进行程序控制(管理函数调用和 returns,以及用于本地数据的适量 space)和用于操作数据的其他内存.所以 stack space 在很大程度上是程序设计的函数(它是固定的)而不是问题大小。该模型运行良好,因此我们继续使用它。

脚注

1 例如,编译器可以报告,对于每个不使用具有 运行 时间变量大小的对象的例程,使用的最大值 space通过它的任何路径中的例程。链接器或其他工具可以报告,对于任何调用树 [因此没有循环] 使用的最大堆栈 space。其他工具可以帮助分析具有潜在递归的调用图中的堆栈使用。

How come the stack cannot be increased during runtime in most operating system?

Linux 这是错误的。在最近的 Linux 系统上,每个线程都有自己的 call stack (see pthreads(7)), and an application could (with clever tricks) increase some call stacks using mmap(2) and mremap(2) after querying the call stacks thru /proc/ (see proc(5) and use /proc/self/maps) like e.g. pmap(1)

当然,这样的代码是特定于体系结构的,因为在某些情况下调用堆栈会向增加地址的方向增长,而在其他情况下会向减少地址的方向增长。

另请阅读 Operating Systems: Three Easy Pieces and the OSDEV wiki, and study the source code of GNU libc

顺便说一句,Appel 的书 Compiling with Continuations, his old paper Garbage Collection can be faster than Stack Allocation and this paper on Compiling with Continuations and LLVM 可能会让您感兴趣,并且两者都与您的问题非常相关:有时,几乎“没有调用堆栈”,“增加它”是没有意义的。