c++ - 为什么我们在内存中限制堆栈的大小而不是堆的大小

标签 c++ memory stack

这个问题在这里已经有了答案:





why is stack memory size so limited?

(8 个回答)


去年关闭。




我主要用C++编程。我从很多地方看到我应该把大对象(比如 10k 个元素的数组)放在堆上(使用 new)而不是放在堆栈上(使用纯数组类型)。
我真的不明白。原因可能是因为堆栈的滥用导致运行时出现堆栈溢出错误。但是为什么操作系统要为进程(或更准确地说,线程)的堆栈大小设置限制,因为虚拟内存可以根据需要(或在实践中为 4G)变得尽可能大。
谁能帮帮我,我真的不知道。

最佳答案

传统和线程。

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

堆通常在线程之间共享;当它们不是时,它们不必是连续的。

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

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

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

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

相比之下,堆有 tebibytes。

更重要的是,堆栈上的大对象对缓存一致性没有太大帮助;没有 CPU 缓存可以容纳 tront 和 back。如果您正在大量使用它,那么必须遵循单个指针是微不足道的,甚至可以确保堆栈更好地保留在缓存中。

所以 (a) 堆栈大小成本随线程而变化 (b) 地址空间可能受到限制 (c) 巨型堆栈的好处很小。

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

关于c++ - 为什么我们在内存中限制堆栈的大小而不是堆的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62351937/

相关文章:

C++ 两个派生类中有彼此的对象(包括问题)

c++ - 分配类型为自己类 C++ 的 vector 的内存

c++ - 处理内存池中的碎片?

java - 有没有办法在堆栈中搜索带有 "any"参数的内容?

java - 如何找到两个堆栈中的第一个共同出现?

c++ - C/C++ 通用控件检测 TVItem 的双击

c++ 使用 winmain()

C++ 将非英文文本写入文件

c# - .net 词典使用多少哈希桶?

java - 无法理解我需要在 Java while 循环的条件下检查什么