【进程概念】虚拟内存与页表简述

简介: 【进程概念】虚拟内存与页表简述

前言:

一个系统中的进程是与其他进程共享CPU和主存资源的。早期的PC使用物理寻址,而且诸如数字信号处理器、嵌入式微控制器以及Cray超级计算机这样的系统仍然继续使用这种寻址方式。然而现代处理器使用的是一种称为虚拟寻址(virtual addressing)的寻址形式。

物理寻址和虚拟寻址

物理寻址:

CPU想要访问哪个地址就直接访问,中间没有翻译的过程。

虚拟寻址:

使用虚拟地址,CPU通过访问页表得到一个虚拟地址,这个虚拟地址在被送到内存之前需要先转换成物理地址。将一个虚拟地址转换成物理地址的过程我们叫做地址翻译。这个过程需要CPU中的内存管理单元(MMU) 的专用硬件来操作。页表的内容由操作系统管理。

虚拟内存

为了更加有效的管理内存并且减少出错,现代系统提供了一种对主存的抽象概念,叫做虚拟内存(VM)。虚拟内存是硬件异常、硬件地址翻译、主存、磁盘文件和内核软件的完美交互,它为每个进程提供了一个大的、一致的私有地址空间

虚拟内存的意义:

1、它将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保留活动区域,并根据需要在磁盘和主存之间来回的传送数据,高效的使用了主存。

2、它为每个进程提供了一致的地址空间,简化了内存管理。

3、它保护了进程的地址空间不被其他进程破坏。

以上是我们之前介绍的程序的地址空间,但是这是不准确的,应该称为进程的地址空间。

由于虚拟内存概念的引入,每一个进程都拥有一个一致的虚拟地址空间,这使得我们操作系统能以统一的视角来看待每一个进程。

进程的虚拟地址空间分为用户虚拟地址空间和内核虚拟地址空间,所以进程共享内核虚拟地址空间,但每个进程有独立的用户虚拟地址空间。在用户地址空间内,又划分出堆区、栈区、数据区等区域。

mm_struct结构体

实际上,在我们的task_struct(PCB)中,进程的整体虚拟地址空间是由一个结构体mm_struct来描述的,每一个进程的task_struct里面都有一个mm_struct类型的指针变量,指向的内容用来描述整个进程的虚拟内存。

mm_struct源码片段

unsigned long start_code, end_code, start_data, end_data;               
//开始代码段,结束代码。开始数据,结束数据
unsigned long start_brk, brk, start_stack;                              
//堆的开始和结束。
unsigned long arg_start, arg_end, env_start, env_end;                   
//参数的起始和结束,环境变量的起始和终点

页表

页表是一种特殊的数据结构,放在系统空间的页表区,存放逻辑页与物理页帧的对应关系。 每一个进程都拥有一个自己的页表,PCB表中有指针指向页表。 (百度百科)

页表本身并不直接包含在task_struct中,因为它们通常是由操作系统管理的,而且可能会因为转换表的更新而变得非常大,所以不适合包含在控制结构中。页表是在物理内存中,由操作系统的内存管理系统维护。

简单来说,页表存放实现虚拟地址和物理地址映射的一种数据结构,通过查询页表我们就能找到相对应的物理地址。

解释父子进程的虚拟地址以及页表的关系

当某一个创建一个子进程,除了拷贝各种资源外,子进程会拷贝(写时拷贝)一份父进程的页表,页表内容与父进程一致

由于写时拷贝的机制,当子进程想要修改某个物理地址上的内容时,系统会重新给子进程找一片空间。该空间上的内容与父进程的一致,子进程在此空间上做修改不影响父进程,并且系统会调整子进程页表的映射的物理空间,使得子进程页表的映射不发生冲突。

观察以下代码:

果然,虽然虚拟地址一样,但是父子进程的页表中映射的物理地址不一样。(开始的时候一样,但是由于子进程发生了写入操作,使得系统重新找了一个物理空间)

知道了页表的作用,我们也能知道为什么不允许数组越界访问,因为在查页表的时候根本就没找到所访问的虚拟地址,更别谈去访问物理地址了。这样一来,我们也能理解页表其实也起到了保护内存的作用。

相关文章
|
24天前
|
存储 缓存 Linux
【Linux】进程概念(冯诺依曼体系结构、操作系统、进程)-- 详解
【Linux】进程概念(冯诺依曼体系结构、操作系统、进程)-- 详解
|
1天前
|
Linux Shell
Linux进程——Linux进程的概念(PCB的理解)
Linux进程——Linux进程的概念(PCB的理解)
|
9天前
|
存储 安全 Python
进程通信 , 信号量 , 队列 , 管道 , 共享内存
进程通信 , 信号量 , 队列 , 管道 , 共享内存
|
17天前
|
存储 缓存 监控
深度解析操作系统中的核心组件:进程管理与内存优化
【5月更文挑战第29天】 在现代计算技术的心脏,操作系统扮演着至关重要的角色。它不仅管理和控制计算机硬件资源,还为应用程序提供了一个运行环境。本文将深入探讨操作系统中的两个核心组件——进程管理和内存管理,并分析它们对系统性能的影响以及如何通过技术手段实现优化。通过对操作系统内部机制的剖析,我们将揭示这些组件是如何相互作用,以及它们如何共同提升系统的响应速度和稳定性。
|
18天前
|
存储 调度
进程与线程(概念、并行、并发)
进程与线程(概念、并行、并发)
|
19天前
|
存储 缓存 Java
简单介绍一下什么是“工作内存”和“主内存”(JMM中的概念)
该文介绍了Java多线程中`volatile`关键字确保内存可见性的概念。
24 0
|
22天前
|
算法 调度
【操作系统】处理机调度的基本概念和三个层次、进程调度的时机和方式、调度器、闲逛线程
【操作系统】处理机调度的基本概念和三个层次、进程调度的时机和方式、调度器、闲逛线程
53 3
|
22天前
|
调度 索引
【操作系统】进程的基本概念&进程的状态与转换&进程的组织方式
【操作系统】进程的基本概念&进程的状态与转换&进程的组织方式
24 2
|
24天前
|
消息中间件 存储 安全
【Linux 系统】进程间通信(共享内存、消息队列、信号量)(下)
【Linux 系统】进程间通信(共享内存、消息队列、信号量)(下)
|
24天前
|
消息中间件 算法 Linux
【Linux 系统】进程间通信(共享内存、消息队列、信号量)(上)
【Linux 系统】进程间通信(共享内存、消息队列、信号量)(上)

相关实验场景

更多