Memory management 访问进程内存部件

Memory management 访问进程内存部件,memory-management,process,operating-system,kernel,virtual-memory,Memory Management,Process,Operating System,Kernel,Virtual Memory,我目前正在学习操作系统的内存管理。老师说, 事实上,你可能有,而且通常情况下可能有 可以是进程内存的几个部分,这些部分甚至在 全部的也就是说,它们既不是从内存执行、加载或存储的 我不明白这个说法,因为即使在一个简单的C程序中,我们也可以访问它的整个地址空间。我们不是吗 #include <stdio.h> int main() { printf("Hello, World!"); return 0; } #包括 int main() { printf(“你好,世界!”)

我目前正在学习操作系统的内存管理。老师说,

事实上,你可能有,而且通常情况下可能有 可以是进程内存的几个部分,这些部分甚至在 全部的也就是说,它们既不是从内存执行、加载或存储的

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

#include <stdio.h>
int main()
{
   printf("Hello, World!");
   return 0;
}
#包括
int main()
{
printf(“你好,世界!”);
返回0;
}

你能解释一下这句话吗?如果可能,您能否提供一个示例程序,其中运行时“进程内存的几个部分,甚至根本没有被访问过”。

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

大多数程序都有各种不使用的可选部分(例如,可能与图形一起工作的程序会有一些每像素16位的代码和其他每像素32位的代码,并将确定使用哪些代码而不使用其他代码)。大多数堆分配器都是“急切”的(例如,他们会向操作系统请求20兆字节的空间,然后可能只会“
malloc()
2兆字节的空间)。有时程序会内存映射一个大文件,但只访问其中的一小部分


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

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

大多数程序都有各种不使用的可选部分(例如,可能与图形一起工作的程序会有一些每像素16位的代码和其他每像素32位的代码,并将确定使用哪些代码而不使用其他代码)。大多数堆分配器都是“急切”的(例如,他们会要求操作系统提供20兆字节的空间,然后可能只会“
malloc()
2兆字节的空间)。有时程序会内存映射一个大文件,但只访问其中的一小部分


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

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

当程序运行时,它会快速启动页面错误,因为内存中没有任何内容,操作系统必须从辅助存储加载它

如果您的程序没有引用某些内容,则它永远不会加载到内存中

如果将全局变量声明为

char-somedata[1045]


你的程序永远不会引用这个变量,它也永远不会被加载到内存中。代码也是如此。如果你有几页代码完成了执行(例如错误处理代码)它不会被加载。如果您链接到共享库,您可能会包含许多从未使用过的函数。同样,如果您不执行这些函数,它们也不会被加载。

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

当程序运行时,它会快速启动页面错误,因为内存中没有任何内容,操作系统必须从辅助存储加载它

如果您的程序没有引用某些内容,则它永远不会加载到内存中

如果将全局变量声明为

char-somedata[1045]


你的程序永远不会引用这个变量,它也永远不会被加载到内存中。代码也是如此。如果你有几页代码完成了执行(例如错误处理代码)它不会被加载。如果您链接到共享库,您可能会包含许多从未使用过的函数。同样,如果您不执行它们,它们也不会被加载。

首先,并非所有的地址空间都始终由物理内存支持,特别是如果您的地址空间包含248+字节,而您的co计算机并没有(这并不是说你们不能把大部分地址空间映射到一个物理内存页上,而这个物理内存页对任何事情都没有什么用处)

然后,地址空间的某些部分可能会故意永久不可访问,比如虚拟地址附近的一些页面