堆栈大小与虚拟内存的关系

问题描述 投票:0回答:1

在我们的操作系统课程中,我们提到虚拟内存是一种将物理内存抽象为进程的机制,它看起来像这样(每个进程):

栈沿着内存地址向下增长,堆沿着内存地址向上增长。堆栈起始地址几乎是地址空间的最大地址(在 64 位处理器上约为 2^64 - 1)。

我确实了解虚拟内存、堆栈和堆,但我不明白为什么堆栈大小应限制为只有几 MB 基于此图片(实际上,由于缓存,堆栈只有几 MB,并且大的堆栈大小表明代码中存在问题)。理论上,只有当我们用完系统内存时才会发生堆栈溢出,而不是当我们填满 1-3MB 时。

我的问题是:这张图片中是否还缺少另一条断线,该断线是由编译器/链接器/操作系统设置的,用于标记最大堆栈大小?

heap-memory stack-overflow virtual-memory stack-memory
1个回答
0
投票

没有绝对疯狂的递归级别,没有真正需要在任何地方有一个接近千兆字节级别的堆栈。

由于您通常事先知道什么级别的堆栈就足够了,因此限制堆栈大小并允许堆不受限制的访问是完全可以接受的。如果您仅推送基本类型(包括指针),1M 堆栈实际上相当大。例如,每次调用平均(这是很多)10 个 8 字节参数(并加倍以用于额外的管理堆栈使用),您可以在不耗尽堆栈的情况下遍历 6,000 多个堆栈级别。

通常,当链接器将所有目标文件组合成可执行文件时,堆栈大小是由链接器设置的(例如,我相信 GNU 链接编辑器

ld
使用(或曾经使用过)指定了堆栈大小的脚本)。

你完全正确,你可以只共享堆底部和堆栈顶部之间的空间,以便它们都可以自由使用它。


但是您还应该记住,如果您的进程启动多个线程(相同的进程空间),它们每个都会有自己的自己的堆栈。无论是来自堆分配还是来自主堆栈下的另一个部分,都是一个实现决策。

© www.soinside.com 2019 - 2024. All rights reserved.