【问题标题】:Can the stack grow into the heap?栈可以长成堆吗?
【发布时间】:2019-05-09 13:56:22
【问题描述】:

我目前正在学习操作系统,我了解到堆栈位于内核和堆之间。令我困惑的是,在大多数实现中,由于堆栈趋于向下增长,而堆增长到更高的内存地址,是什么阻止了堆栈增长到堆中?如果有可能,如果它确实增长到堆中会发生什么?

【问题讨论】:

    标签: operating-system heap-memory stack-memory


    【解决方案1】:

    传统上非常简化的内存视图如下所示:

     ===================
    | Operating System  | High memory
     ===================
    |   Your program    |
    |  ---------------  |
    | | Process stack | |
    |  ---------------  | Transient program area
    | |  Process heap | |
    |  ---------------  |
    | |  Program code | |
    |  ---------------  |
     ===================
    | Operating system  | Low memory
     ===================
    

    正如您所指出的,进程堆栈从操作系统代码下方开始,然后向下增长。另一方面,进程堆从固定程序代码的上方开始,然后向上增长。

    在早期的 PC 操作系统中,这实际上是内存中程序的物理布局。例如,CP/M 操作系统为某些操作系统引导代码保留了前 256 个字节的内存,其余必要的操作系统服务占用了高内存区域。程序从地址 0x0100 开始,并且可以使用从那里到顶部操作系统代码开始之间的所有内存。 MS-DOS 非常相似。

    没有任何防护措施可以防止您提到的事情发生:程序会在堆栈上分配如此多的空间,以至于它会覆盖在堆上分配的内存。或者,程序将分配覆盖处理器堆栈的堆内存。当这些事情发生时,程序就会崩溃。在某些情况下,操作系统也会崩溃。当然,因为一次只能运行一个程序,这没什么大不了的:只需重新启动机器并重试即可。

    现代计算机具有更先进的内存布局,而这种概念图不再适用。今天的操作系统可以更好地执行内存访问限制。例如,一个进程为其堆栈分配了一个固定段(通常大约为 1 兆字节)。如果程序试图使用比分配更多的堆栈空间,内存管理器将不允许它。该程序将因访问冲突而崩溃。并且程序的堆不能增长到分配给栈的内存中也是出于同样的原因。

    【讨论】:

    【解决方案2】:

    这不一定正确:

    我目前正在学习操作系统,我了解到堆栈位于内核和堆之间。

    堆栈和堆只是内存。除了如何使用它们之外,它们是无法区分的。地址空间中可以有多个堆和多个栈。

    堆不能增长到堆栈中,反之亦然。操作系统不允许堆重新分配已分配给堆栈的内存。

    人们可以访问超出堆栈末尾的内存,理论上,堆栈可能是堆的一部分。一些操作系统将不可访问的守卫放在堆栈的末尾。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-29
      • 2010-09-17
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      • 2017-08-16
      • 2011-06-01
      相关资源
      最近更新 更多