物理内存中的堆和栈在哪里?

4

我通过谷歌搜索了解了堆栈(Heap & Stack)的概念和区别, 但我还想了解其他方面的问题。

  1. 堆和栈在物理内存中的位置是什么?

  2. 它们的大小是多少?例如,如果我使用12GB记忆体,那么堆的大小是多少?栈的大小又是多少?

  3. 是谁创造了这两种不同的概念?

  4. 我可以操纵堆和栈的分配吗?如果它们各占内存的50%(如果在我的情况下堆占用了6GB内存,则栈也占用了6GB内存),我可以调整它们的大小吗?


请每次只提一个问题。 - Lightness Races in Orbit
1
在现代PC类型的系统上,如Windows、Mac OSX和Linux,所有内存(无论它被称为堆栈、堆或其他任何东西)都是虚拟内存,其中的部分可能映射到物理内存,而其他部分可能被交换到磁盘。此外,回答您的一个问题,堆栈内存是每个进程的。 - Some programmer dude
没有所谓的“位置”。RAM 就是 RAM,所有东西都可以在任何地方。 - deviantfan
1
@JoachimPileborg 你的意思是每个线程。通常是这样的。或者协程。噢,不好了。 - sehe
我不知道为什么有一种趋势关闭与计算机科学相关的问题..这个社区是关于什么的?是关于烹饪还是其他什么? - Meto
2个回答

5
正如标题所说,堆和栈在物理内存中的位置在哪里?
自从CPU拥有MMUs以在虚拟内存和物理内存之间添加一层间接性以来,堆和栈就可以出现在物理内存的任何地方。自从现代操作系统实现了ASLR以来,堆和栈也可以出现在虚拟内存的任何地方。
它们的大小如何?例如,我在我的台式电脑上使用了12 GB的内存,那么堆有多大?栈有多少大小?
两者都是按需启动并逐渐增长的。在Unix上,最大栈大小由ulimit -s设置,而堆大小受ulimit -d限制。您可以使用ulimit -a查看Unix OS默认设置的限制。
这两种不同类型的概念是由谁创建的?
我敢打赌这至少可以追溯到1960年代。维基百科有一个来自1960年的参考资料。
  1. 如果堆和栈每个占用50%的内存(如果在我的情况下堆占用6GB内存,栈也占用6GB内存),我能否操纵堆栈的分配?我能调整它们的大小吗?
正如已经提到的,它们会自行调整大小,更准确地说,它们会根据操作系统和用户设置的限制按需增长。如果您正在使用Unix和bash,请参阅ulimit的帮助文档。

1

1. 它可以到处存在。即使在物理内存之外,因为在应用程序方面没有这样的东西。用户空间中的所有内容都使用虚拟内存,可以映射到RAMHDD上的交换区域。这里没有任何确定的假设,抱歉。

2. 它们都是动态增长的,区别在于速度和大小限制:

  • 堆栈通常被认为较慢。它根据应用程序要求进行分配。它的大小与RAM的数量相同,甚至更大(分页)。

  • 堆栈要快得多,因为它通过简单移动堆栈指针来“分配”。它通常有大小限制。例如,在C++中,此限制在编译阶段设置(GCC上的ulimit -s,MSVC上的/STACK:reserve/STACK:reserve,commit)。

栈通常比较小,很容易溢出(这就是我们所说的堆栈溢出)。例如,在C++中,您很可能无法执行以下操作:

int main()
{
    int large_array[1000000];
    return 0;
}

因为:

enter image description here

While this is perfectly fine:

int main()
{
    int* large_array = new int[1000000]; //allocated from heap
    return 0;
}

3. 一些非常聪明的人。

4. 仔细阅读1-3点,你就会知道答案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接