访问过程存储部件

时间:2019-03-16 17:00:58

标签: memory-management process operating-system kernel virtual-memory

我目前正在研究the video lecture操作系统的内存管理。讲师说,

  

实际上,您可能有,而且在很多情况下   是过程存储器的几个部分,甚至在以下位置都无法访问   所有。也就是说,它们既不会从内存中执行,加载或存储。

我不明白这句话,因为即使在一个简单的C程序中,我们也会访问它的整个地址空间。不是吗?

#include <stdio.h>
int main()
{
   printf("Hello, World!");
   return 0;
}

您能解释一下这句话吗?如果可能的话,您可以提供一个示例程序,其中“进程存储器的几个部分,在运行时甚至根本无法访问”。

3 个答案:

答案 0 :(得分:1)

假设您有一个庞大而复杂的实用程序(例如,编译器),并且用户向其寻求帮助(例如,他们键入gcc --help而不是要求它编译任何东西)。在这种情况下,会使用多少实用程序的代码和数据?

大多数程序具有未使用的各种可选部分(例如,与图形兼容的某些东西将具有一些用于每个像素16位的代码,以及用于每个像素32位的其他代码,并将确定要使用和不使用的代码其他代码)。大多数堆分配器都是“渴望的”(例如,他们会要求操作系统提供20 MiB的空间,然后可能仅“ malloc() 2 MiB的空间)。有时程序会内存映射一个巨大的文件,但随后只能访问一个一小部分。

即使是琐碎的“ hello world”示例代码;虚拟地址空间可能包含一个巨大的(几个MiB)共享库,以支持许多C标准库函数(例如puts()fprintf()sprintf()等),并且仅您的程序使用该共享库的一小部分;并且您的程序可能会为其堆栈保留一个保守的空间(例如,其堆栈可能会保留20 KiB的空间),然后可能仅使用数百个字节的堆栈。

答案 1 :(得分:1)

在虚拟内存系统中,进程的地址空间是在启动时在辅助存储区中创建的。几乎没有或什么都没有放置在内存中。例如,操作系统可以使用可执行文件作为代码和静态数据的页面文件。它只是建立了一个内部结构,该结构表示某些内存范围已映射到可执行文件中的这些块。共享库也是如此。其他数据将映射到page file

在您的程序运行时,它开始快速启动页面错误,因为内存中没有任何内容,并且操作系统必须从辅助存储中加载它。

如果程序没有引用某些内容,则永远不会将其加载到内存中。

如果您将全局变量声明为

char somedata [1045];

,并且您的程序从不引用该变量,也永远不会将其加载到内存中。代码也一样。如果您的代码页已完成执行(例如错误处理代码),则不会加载该页面。如果链接到共享库,则可能会包含很多从未使用过的功能。同样,如果不执行它们,则不会加载它们。

答案 2 :(得分:0)

首先,并不是所有的地址空间都始终由物理内存支持,尤其是如果您的地址空间覆盖了2 48 + 个字节,而您的计算机则没有(这是并不是说您不能将大部分地址空间映射到单个物理内存页面,这对任何东西都没有多大用处。

然后可能有目的地永久地无法访问地址空间的某些部分,例如虚拟地址0附近的几页(以捕获NULL指针取消引用)。

正如在其他答案中指出的那样,在按需加载程序时,您可能为程序保留了部分地址空间,但是如果该程序恰巧不需要其任何代码或那里的数据,那里也不需要加载程序。