提问人:Tarun Mendu 提问时间:8/18/2023 最后编辑:BarmarTarun Mendu 更新时间:8/24/2023 访问量:64
如果堆是动态的,那么为什么它被放置在堆栈和数据区域之间
If Heap is dynamic then why it is placed in between stack and data area
问:
我目前正在学习操作系统,并对此感到震惊。
如果堆区域的大小是动态的,那么为什么它被放置在堆栈的底部。
如果堆的大小增加,堆栈的起始内存(如图中的MAX_SIZE)也会增加到更高的地址以容纳堆的空间,或者限制使用堆栈和数据区域之间的空间。
PS:我在网上搜索了这个,但没有找到我要找的东西。
答:
堆栈由操作系统指定固定大小。编译时,指令会用完堆栈,并且在编译过程中已经知道堆栈内存使用情况。例如,如果输入一个具有 2 个 64 位变量的函数,则编译器会通过生成访问指令(反之亦然)来保留 8 个字节的堆栈。决定堆栈在虚拟内存中的位置的只是操作系统为 STACK_POINTER 选择的值。mov STACK_POINTER, SOME_DATA
mov STACK_POINTER - 8, SOME_DATA
特定函数使用的堆栈数量是已知的,因此您的工作是确保堆栈不会被过度使用,因为它的大小有限。
对于堆,访问是绝对的,并且地址由操作系统通过查看可用的虚拟内存页来动态选择。就 cpu 指令而言,它只是一个寄存器,用于存储对操作系统进行的系统调用的返回。应用程序进行系统调用,当系统调用返回时,程序中的进一步指令假定相应的寄存器包含用于数据存储的可用地址,或者可能包含错误代码。
由于使用了分页,因此虚拟地址空间具有数十万 GB 的可用空间。就可以分配的数据量而言,这取决于虚拟内存与物理内存的关联可以延迟多少。只要您实际上不写入动态(堆)虚拟内存,操作系统甚至不必将区域(页面)与物理位置相关联。这是因为该内存区域未被修改,因此它不包含任何需要跟踪的有价值内容。因此,只要操作系统不包含有价值的东西,它就可以延迟其与物理内存的关联。一旦完成,操作系统必须将其保留在某个地方(RAM或SWAP)。因此,可以肯定地说,当您拥有超过 ram + 交换的初始化/有价值数据时,操作系统的空间已经用完,并且可能会通过拒绝进一步分配、终止应用程序或其他方式做出反应。
总之,虚拟地址空间是如此之大,以至于操作系统在堆与堆栈相遇之前就耗尽了空间。如果是这样,那么您的计算机已经用完了数千次空间,并且操作系统不允许您去那里。
评论
sbrk
mmap