0

可能重复:
堆栈内存如何增加?

让我们考虑一个使用分段的操作系统。
我的问题是:操作系统是否会接收堆栈指针的每次更改
并立即(或相当立即)分配/释放物理内存中的空间,
或者它使用一种聪明的策略来分配比您减少 sp 时所需的内存更多的内存,释放内存只有当释放的内存达到一定数量时?

我希望我的问题足够清楚。

4

2 回答 2

1

如果我理解你在问什么,答案如下:

操作系统在进程创建开始时为堆栈分配一定的空间。当堆栈操作发生时,处理器会自动增加和减少堆栈指针,并且软件会减少堆栈指针以分配临时数据的空间(如在函数调用中)。递减是因为栈实际上是向下增长的,如果指针超过给定的分配空间就会发生栈溢出。分配的空间量因系统而异。操作系统可以做的唯一可能的“技巧”是分页,它可以将内存标记为已分配,但在软件使用它之前不会实际分配物理内存。这称为需求分页,并且在堆而不是堆栈中具有更多应用。

于 2012-07-20T19:54:52.507 回答
0

还要添加到上面的答案..
进程的堆栈向堆向下增长,操作系统必须确保这些区域不重叠。
当堆栈需要更多空间(即堆栈指针指向非法/未分配的内存)时,会导致页面错误。

  1. 页面错误的中断处理程序是这样编写的,它读取当前堆栈指针,它的最大限制是查找页面错误是由于堆栈增长还是因为我们触及了部分虚拟内存(属于代码/数据)而不是尚未映射到物理内存(需求分页)。
  2. 如果由于堆栈增长而发生页面错误
    • 我们检查是否达到堆栈的最大大小,在 GNU/Linux 系统上它是 8Mb(默认)
    • 接下来我们通过分配一个新的页面到堆栈来看看它是否会与堆重叠
    • 这之后可能会进行更多的健全性检查。
    • 如果以上所有都通过,则分配一个新页面
    • 如果其中一项检查失败,则根据实现将出现段错误或堆栈溢出。
  3. 如果我们在上一步中确实分配了一个新页面,则更新错误进程的堆栈指针,将新映射添加到错误进程的页表中,并且页面错误处理程序将控制权返回给错误指令,通常是推送或 pusha(在汇编中,x86)。

PS:以上步骤来自我基于pintos OS的UG OS课程的OS作业,实际步骤可能会有所不同(在像linux这样的OS中会很复杂)。这里链接到部分堆栈增长见4.3.3节。

于 2012-07-21T08:38:30.687 回答