Soh*_*mad 7 c operating-system
我对这些概念很陌生,但我想问你一个我认为非常基本的问题,但我很困惑,所以我问它.问题是......过程的大小如何由操作系统决定?首先让我清楚一下,假设我已经编写了一个C程序,我想知道它将占用多少内存,我该如何确定它?其次我知道有许多部分,如代码部分,数据部分,流程的BSS.现在它们的大小是预先确定的吗?其次,如何确定堆栈和堆的大小.堆栈和堆的大小是否也很重要,同时计算进程的总大小.
我们再次说,当我们加载程序时,给进程一个地址空间(由base和limit寄存器完成并由MMU控制,我猜)当进程试图访问不在其中的内存位置时地址空间我们得到分段错误.进程如何访问不在其地址空间中的内存.根据我的理解,当发生一些缓冲区溢出时,地址就会被破坏.现在当进程想要访问损坏的位置时,我们就会得到分段错误.是否有任何其他地址违规方式.
第三,为什么堆栈向下增长并向上堆积.这个过程与所有操作系统相同.它如何影响性能.为什么我们不能以其他方式拥有它?
如果我在任何陈述中出错,请纠正我.
谢谢Sohrab
当进程启动时,它会获得自己的虚拟地址空间。虚拟地址空间的大小取决于您的操作系统。一般来说,32 位进程获得 4 GiB(4 giga 二进制)地址,64 位进程获得 18 EiB(18 exa 二进制)地址。
您无法以任何方式访问未映射到虚拟地址空间的任何内容,因为根据定义,未映射到虚拟地址空间的任何内容都没有适合您的地址。您可能会尝试访问当前未映射到任何内容的虚拟地址空间区域,在这种情况下,您会收到段错误异常。
在任何给定时间,并非所有地址空间都映射到某些内容。而且,并非所有数据都可以被映射(可以映射多少数据取决于处理器和操作系统)。在当前一代英特尔处理器上,最多可以映射 256 TiB 的地址空间。请注意,操作系统可以进一步限制这一点。例如,对于 32 位进程(最多具有 4 GiB 地址),Windows 默认情况下为系统保留 2 GiB,为应用程序保留 2 GiB(但有一种方法可以为系统保留 1 GiB,为应用程序保留 3 GiB)。
在应用程序运行时,正在使用的地址空间的大小和映射的地址空间的大小会发生变化。操作系统特定的工具可让您监视当前为正在运行的应用程序分配的内存和虚拟地址空间。
代码段、数据段、BSS 等术语指的是链接器创建的可执行文件的不同区域。一般来说,代码与静态不可变数据分开,静态不可变数据与静态分配但可变的数据分开。堆栈和堆与上述所有内容都是分开的。它们的大小由编译器和链接器计算。请注意,每个二进制文件都有自己的部分,因此任何动态链接库都将分别映射到地址空间中,每个库都有自己的部分映射到某处。然而,堆和堆栈不是二进制映像的一部分,通常每个进程只有一个堆栈和一个堆。
堆栈的大小(至少初始堆栈)通常是固定的。编译器和/或链接器通常有一些标志,您可以使用它们来设置运行时所需的堆栈大小。堆栈通常“向后增长”,因为这就是处理器堆栈指令的工作方式。让堆栈朝一个方向增长,其余部分朝另一个方向增长,可以在您希望两者都不受限制但不知道每个方向可以增长多少的情况下更容易组织内存。
一般来说,堆是指进程启动时未预先分配的任何内容。在最低级别,有几个与堆管理相关的逻辑操作(并非所有操作都按照我在所有操作系统中描述的方式实现)。
虽然地址空间是固定的,但某些操作系统会跟踪进程当前回收的部分地址。即使情况并非如此,流程本身也需要对其进行跟踪。因此,最低级别的操作是实际决定将使用地址空间的某个区域。
第二个低级操作是指示操作系统将该区域映射到某个区域。这个一般可以
一些不可交换的内存
可交换并映射到系统交换文件的内存
可交换并映射到其他文件的内存
可交换并以只读模式映射到其他文件的内存
另一个虚拟地址区域映射到的相同映射
与另一个虚拟地址区域映射到的相同映射,但处于只读模式
与另一个虚拟地址区域映射到的映射相同,但处于写时复制模式,复制的数据映射到默认交换文件
可能还有其他组合我忘了,但这些是主要的。
当然,所使用的总空间实际上取决于您如何定义它。当前使用的 RAM 与当前映射的地址空间不同。但正如我上面所写,依赖于操作系统的工具应该可以让您了解当前发生的情况。
| 归档时间: |
|
| 查看次数: |
2865 次 |
| 最近记录: |