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



这是为了避免碎片化吗?还是其他原因?与具有手动生存期的malloc()相比,内存分配的设置生存期是一个非常有用的构造。

在程序执行过程中,当函数被调用和返回时,用于堆栈的空间会频繁增加和减少。堆栈允许的最大空间通常是固定的限制。

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

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

理论上,一个程序可以被给予一个小的初始限制,如果它发现自己在处理一个"大"问题,可以告诉操作系统它打算使用更多。这仍然可以捕获大多数"失控"程序,同时允许精心制作的程序使用更多空间。然而,总的来说,我们设计程序使用堆栈进行程序控制(管理函数调用和返回,以及适度的本地数据空间(和其他内存来操作数据。因此,堆栈空间在很大程度上是程序设计的函数(它是固定的(,而不是问题大小。这个模型一直运行良好,所以我们继续使用它

脚注

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

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

这对Linux来说是错误的。在最近的Linux系统上,每个线程都有自己的调用堆栈(请参阅pthreads(7((,应用程序可以(巧妙地(在通过/proc/查询调用堆栈后(请参阅proc(5(并使用/proc/self/maps(使用mmap(2(和mremap(2。

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

另请阅读操作系统:三个简单的部分和OSDEV wiki,并研究GNU libc的源代码。

顺便说一句,Appel的书《用连续性编译》,他的旧论文《垃圾收集》可以比《堆栈分配》更快和这篇关于《用连续化编译》和《LLVM》的论文可能会引起你的兴趣,两者都与你的问题非常相关:有时;无调用堆栈";并且";增加它";。

相关内容

最新更新