为什么我们限制堆栈大小而不限制内存堆

时间:2020-06-12 20:22:21

标签: c++ memory stack

我主要使用C ++进行编程。我从很多地方看到,我应该将大型对象(如10k元素的数组)放在堆上(使用new),而不是放在堆栈上(使用纯数组类型)。 我不太了解原因可能是因为许多堆栈滥用会在运行时导致堆栈溢出错误。但是,由于虚拟内存可以随需要而变大(实际上是4G),因此OS为什么要为进程(或更准确地说是线程)的堆栈大小设置限制。 谁能帮我,我真的不知道。

2 个答案:

答案 0 :(得分:4)

传统和线程。

堆栈是每个线程的,为了提高效率,必须是连续的内存空间。不连续的堆栈会使每个函数的调用变得更加昂贵。

通常在线程之间共享堆;如果不是,则不必是连续的。

在32位天中,拥有1000个线程并不是不可能的。每个线程1兆字节,即1 GB的地址空间。 1兆不是那么大。

相比之下,2 gigs的堆服务所有线程。

在64位系统上,可寻址内存通常少于64位。以40位为单位,如果您将一半的地址空间分配给堆栈,并且有10,000个线程,则每个堆栈只有50兆。

48位是更常见的,但是每个堆栈仍然只有千兆字节的地址空间。

相比之下,堆有tebibytes。

在堆栈上放置一个大对象对缓存一致性没有多大帮助;没有CPU缓存可以容纳tron和back。如果您需要大量操作,则必须遵循单个指针是微不足道的,甚至可以确保堆栈更好地保留在缓存中。

因此(a)带有线程的堆栈大小成本尺度(b)地址空间可能受到限制(c)大型堆栈的好处很小。

最后,无限递归是一个常见的错误。您希望在用户外壳程序因资源耗尽而崩溃之前,将堆栈炸开并捕获(二进制加载程序经常用陷阱页面将堆栈包围)。大小适中的堆栈使这种可能性更大。

答案 1 :(得分:-2)

完全可以使用10k INT的静态数组。通常最好使用“ new”,因为当您处理大数据块时,您不能保证它们始终是数组的大小。动态分配内存使您仅使用所需的内存。效率更高。

如果您对操作系统如何选择堆栈大小或“页面”感到好奇,请阅读以下内容: https://en.m.wikipedia.org/wiki/Page_(computer_memory)

此外,我不确定您是否以正确的方式使用“堆”。 “堆”是基于树的数据结构。堆栈指的是可执行文件和进程数据在RAM中的布局。