首页 百科知识 进程的虚拟内存

进程的虚拟内存

时间:2024-10-09 百科知识 版权反馈
【摘要】:进程的虚拟内存包括可执行代码和多个资源数据。此链表按虚拟内存位置来排列由于那些虚拟内存区域来源各不相同,Linux使用vm_area_struct中指向一组虚拟内存处理过程的指针来抽象此接口。为进程创建新虚拟内存区域或处理页面不在物理内存错误时,Linux内核重复使用进程的vm_area_struct数据结构集合。当进程请求分配虚拟内存时,Linux实际上并不直接分配物理内存。当进程试图对新分配的虚拟内存进行写操作时,系统将发生page fault(页失效)。

2.5 进程的虚拟内存

进程的虚拟内存包括可执行代码和多个资源数据。首先加载的是程序映像,例如ls。ls和所有可执行映像一样,是由可执行代码和数据组成的。此映像文件包含所有加载可执行代码所需的信息,同时还将程序数据连接进入进程的虚拟内存空间。然后在执行过程中,进程定位可以使用的虚拟内存,以包含正在读取的文件内容。新分配的虚拟内存必须连接到进程已存在的虚拟内存中才能够使用。

最后Linux进程调用通用库过程,比如文件处理子程序。如果每个进程都有库过程的拷贝,那么共享就变得没有意义。而Linux可以使多个进程同时使用共享库。来自共享库的代码和数据必须连接进入进程的虚拟地址空间以及共享此库的其他进程的虚拟地址空间。

任何时候进程都不同时使用包含在其虚拟内存中的所有代码和数据。虽然它可以加载在特定情况下使用的那些代码,如初始化或者处理特殊事件时,另外它也使用了共享库的部分子程序。但如果将这些没有或很少使用的代码和数据全部加载到物理内存中会引起极大的浪费。如果系统中多个进程都浪费这么多资源,则会大大降低系统效率。Linux使用请求调页技术来把那些进程需要访问的虚拟内存带入物理内存中。内核将进程页表中这些虚拟地址标记成存在但不在内存中的状,而无需将所有代码和数据直接调入物理内存。当进程试图访问这些代码和数据时,系统硬件将产生页面错误并将控制转移到Linux内核来处理之。这样对于处理器地址空间中的每个虚拟内存区域,Linux都必须知道这些虚拟内存从何处而来以及如何将其载入内存以处理页面错误。

Linux内核需要管理所有的虚拟内存地址,每个进程虚拟内存中的内容在其task_struct结构中指向的vm_area_struct结构中描叙。进程的mm_struct数据结构也包含了已加载可执行映像的信息和指向进程页表的指针。它还包含了一个指向vm_area_struct链表的指针,每个指针代表进程内的一个虚拟内存区域。

此链表按虚拟内存位置来排列由于那些虚拟内存区域来源各不相同,Linux使用vm_area_struct中指向一组虚拟内存处理过程的指针来抽象此接口。通过使用这个策略,所有的进程虚拟地址可以用相同的方式处理而无需了解底层对于内存管理的区别。如当进程试图访问不存在内存区域时,系统只需要调用页面错误处理过程即可。

为进程创建新虚拟内存区域或处理页面不在物理内存错误时,Linux内核重复使用进程的vm_area_struct数据结构集合。这样消耗在查找vm_area_struct上的时间直接影响了系统性能。为了加快存取,Linux另外把vm_area_struct数据结构排列成一个AVL(Adelson-Velskii和Landis)树(也称平衡树)。这棵树上,每个vm_area_struct(或节点)有一左一右两个指针指到它的邻近的vm_area_struct结构。左指针指向的节点虚拟地址小于右指针指向的节点类拟地址。寻找正确的节点时,Linux从树根开始,根据每个节点的左右指针指向的地址的大小关系决定向何处去找,直到找到为止。当然,没有免费的午餐,把一个新的vm_area_struct插入到这棵树要花一些额外的处理时间。

当进程请求分配虚拟内存时,Linux实际上并不直接分配物理内存。它只是创建一个vm_area_struct结构来描述此虚拟内存,此结构被连接到进程的虚拟内存链表中。当进程试图对新分配的虚拟内存进行写操作时,系统将发生page fault(页失效)。处理器会尝试解析此虚拟地址,但是如果找不到对应此虚拟地址的页表入口时,处理器将放弃解析并产生页面错误异常,由Linux内核来处理。Linux则查看此虚拟地址是否在当前进程的虚拟地址空间中。如果是Linux会创建正确的PTE并为此进程分配物理页面。包含在此页面中的代码或数据可能需要从文件系统或者交换磁盘上读出。然后进程将从页面错误处开始继续执行,由于物理内存已经存在,所以不会再产生页面异常,可以继续运行。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈