如果堆是动态的那么为什么它被放置在堆栈和数据区域之间

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

我目前正在学习操作系统并对此感到震惊。

  • 如果堆区域的大小是动态的那么为什么它被放置在堆栈的底部。

  • 如果堆的大小增加,堆栈的起始内存(图中的MAX_SIZE)也会增加到更高的地址以容纳堆的空间,或者限制使用堆栈和数据区域之间的空间。

Memory layout

PS:我在网上搜索了这个,但没有找到我要找的东西。

linux memory-management operating-system heap-memory stack-memory
1个回答
0
投票

堆栈由 os 指定固定大小。编译时,指令会使用堆栈,并且堆栈内存的使用情况在编译期间已知。例如,如果您输入具有 2 个 64 位变量的函数,则编译器通过生成访问指令(例如

mov STACK_POINTER, SOME_DATA
mov STACK_POINTER - 8, SOME_DATA
)保留 8 个字节的堆栈,反之亦然。决定堆栈在虚拟内存中的位置的只是操作系统为 STACK_POINTER 选择的值。

特定函数使用的堆栈量是已知的,因此您的工作是确保堆栈不会过度使用,因为它的大小有限。

对于堆,访问是绝对的,并且操作系统通过查看可用的虚拟内存页面动态选择地址。就 cpu 指令而言,它只是一个被选择用于存储对操作系统进行的系统调用的返回的寄存器。应用程序进行系统调用,当系统调用返回时,程序中的进一步指令假定相应的寄存器包含用于数据存储的可用地址,或者可能包含错误代码。

由于使用了分页,虚拟地址空间有数十万GB可用。就可以分配多少数据而言,这取决于虚拟内存与物理内存的关联可以推迟多少。只要您实际上不写入动态(堆)虚拟内存,操作系统甚至不必将区域(页面)与物理位置关联起来。这是因为该内存区域没有被修改,因此它不包含任何需要跟踪的有价值的内容。因此,只要物理内存不包含有价值的东西,操作系统就可以推迟与物理内存的关联。一旦完成,操作系统必须将其保存在某个地方(RAM 或 SWAP)。因此可以肯定地说,当您拥有超过 ram + 交换的初始化/有价值数据时,操作系统已耗尽空间,并且可能会通过拒绝进一步分配、终止应用程序或其他方式做出反应。

总而言之,虚拟地址空间太大,以至于操作系统在堆与堆栈相遇之前就耗尽了空间。如果是这样,那么您的计算机已经耗尽空间数千次,并且操作系统不允许您去那里。

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