首页 > 解决方案 > 包含堆数据或静态变量的数据段

问题描述

我正在阅读(操作系统 - Tannenbaum,第 190 页)关于系统内存的内容,我发现一段说:

数据段用作动态分配和释放的变量的堆,以及普通局部变量和返回地址的堆栈段。

正如数据段所说,它用于初始化静态变量。

其中哪一项是正确的?还是我的理解有问题?

标签: cmemorymemory-managementoperating-system

解决方案


从您的链接本身:

从历史上看,为了能够支持比内部地址寄存器的本机大小更大的内存地址空间,早期的 CPU 实现了一个分段系统,他们将存储一小组索引以用作某些区域的偏移量。Intel 8086 系列 CPU 提供了四个段:代码段、数据段、堆栈段和额外段

现在,操作系统:设计与实现写于 1987 年,当时数据段用于堆栈、堆、初始化数据和未初始化数据。

从那时起,发生了一些重要的变化:

  • 没有更多的内存和更多的 CPU 位,硬件不再需要分段。
  • 段不仅仅是一个硬件工件 - 它们成为一种内存管理设计模式。
  • 引入BSS部分。
  • mmap()POSIX 共享内存 IPC这样的特性意味着堆不是单个连续段。
  • 多线程是指多个栈,在同一个内存空间,共享一个堆。

所以在写这本书的时候,“数据段”是一个由硬件定义的概念,它被定义为包含非本地的所有内容:初始化数据、未初始化数据、动态分配的数据等。

但是现在操作系统的内存管理器将“数据段”定义为“包含程序初始化数据的内存区域”。

在使用数据段指针的 CPU 上,它指向操作系统内存管理器声明为“数据段”的开头。

但是内存管理器有更多的段,用于 BSS 和堆,它们不是由 CPU 指针表示的,所以内存管理器只是将它们放在数据段之后。

如今,堆栈是一个不同的故事。当您创建一个新线程时,它会获得一个新堆栈,通常大小有限(例如,在某些版本的 Linux 上为 8 MB)。最有可能的是,线程的堆栈将从与堆相同的区域分配,这意味着在比数据段更高的地址处,并且由于堆栈增长到较低的地址,所有堆栈仍将向数据段增长


推荐阅读