Linux——进程地址空间

今天,小编和大家一起学习有关进程地址空间的知识。

目录

一.什么是进程地址空间

(一).进程地址空间内部结构

(二).进程地址空间的产生

(三).static、const的本质

二 .进程地址空间与物理内存

(一).关系

 (二).写时拷贝

 三.使用虚拟地址空间的意义

(一).安全性

(二).低耦合

(三).进程独立性

四.程序运行过程


一.什么是进程地址空间

在我们刚学习计算机时,就知道栈区、堆区、常量区...的概念。那时候总以为计算机内存(物理内存)就是按这样排序的。但是,这其实不是物理内存,这是进程地址空间。

(一).进程地址空间内部结构

这里小编选择用一张图来表示其内部结构:

Linux——进程地址空间_第1张图片

(二).进程地址空间的产生

当程序运行时,操作系统不仅将程序加载进进程、创建PCB结构体,还会创建一个mm_struct结构体。mm_struct结构体就是我们所谓的进程地址空间,是一种数据结构。我们在写代码时的那些所谓地址,其实都是mm_struct结构体规定的地址。这些地址并不真实存在。所以我们会发现,所谓进程地址空间就是人为定义的数据结构,且每个进程都有一份!

讲的再通俗一点,每一个进程在创建时,都会得到一个进程地址空间(mm_struct)。它会以为这个就是真实的地址,对数据的操作也会以这个为内存基准。就好比操作系统给它画了个大饼一样。

(三).static、const的本质

总所周知,static变量是只在函数内部能修改,但出了函数又不会销毁,这是因为它定义在初始化/未初始化数据区。因此不像存放在栈区的临时变量那样随着函数销毁而销毁。

const变量的性质是在定义伊始,就不能修改,这是因为它存放在常量区,根据进程地址空间我们可以发现,位置在正文代码区上方。其实本质上也算是在代码区的。与代码区一样具备只读属性。因此,我们无法修改const变量。

所以,所谓变量的特性,其实是它所处的地址区的属性。

二 .进程地址空间与物理内存

(一).关系

知道了进程地址空间是虚拟的,那么我们怎么才能的到真实的地址呢。操作系统在这里采用了映射的方式。在创建mm_struct结构体的同时,也创建了一个页表。页表通过虚拟地址来指向物理地址。这样就完成了由虚拟到物理的转化。

相当于页表是个中间体,它来负责由虚拟地址转为物理地址。

Linux——进程地址空间_第2张图片

 (二).写时拷贝

当创建子进程时,子进程会对父进程的mm_struct、页表也进行一份拷贝。此时,父子进程共享同一块物理内存,即页表所指的物理内存相同。只有当子进程对进程数据进行修改时,操作系统才会为其分配一块物理内存,页表指向该区域,这就是写时拷贝。但是,由于mm_struct是拷贝过来的,子进程数据的虚拟地址与父进程相同,所以即便数据值修改,其虚拟地址也不会修改。所以无论值是否改变,父子数据的虚拟内存地址相同。

 三.使用虚拟地址空间的意义

(一).安全性

代码操作的不是真实的内存,这其实是给内存上了一道锁。举个例子:如果代码出现了地址越界行为。当操作物理内存时,可能会发生越界的正是已定义的其他进程数据,那么极有可能造成其他进程瘫痪,这显然是极度危险的。但是,当操作虚拟地址时,一但越界,进程管理模块会立马发现并报错。

(二).低耦合

进程管理模块对进程地址空间进行管理。而内存管

理模块又对进程管理模块进行管理。假如没有虚拟地址空间概念,内存管理模块需要对物理内存直接管理,让管理复杂化。有虚拟地址后,内存管理模块只需要把这一部分的工作分配给进程管理模块去管理就好。自己只需要操作进程管理模块即可。相当于校长下边又有学生工作部管理学生事务,不需要自己动手去处理,将工作模块化、集合化。

(三).进程独立性

由于每个进程都有属于自己的mm_struct结构体。所以进程之间互不干扰,且在mm_struct内部地址是有序分布的,更利于进程对地址的分配管理。假如直接使用物理地址,不仅进程间可能发生地址冲突(干扰),物理地址本身又是无序的,更不好管理。

四.程序运行过程

这里小编采用图例+文字说明来进行讲解。

首先,我们需要知道,编译器在编译代码时,会按照进程地址空间的定义规则,将代码段转化成虚拟地址,每一条代码都会标记它的下一条代码的地址。所以编译器在编译时,就已经为程序赋予虚拟地址空间了。只不过这时没有mm_struct结构体、页表之类内核数据。

之后,我们假设一个程序运行到这里:

int i = 0;//已运行
func();

当int i = 0; 运行结束后,cpu在物理内存中得到func()的虚拟地址。进而通过页表映射获得func()的物理地址,完成该代码操作,再获得下一条指令地址,继续循环操作。

看图理解~:

Linux——进程地址空间_第3张图片

由此可以发现,CPU得到的是虚拟地址,是用虚拟地址通过映射关系完成对物理内存的相关操作

我们这个世界的一个问题是,蠢人信誓旦旦,智人满腹狐疑。 ——Bertrand Russell


如有错误,敬请斧正

你可能感兴趣的:(Linux,linux,进程地址空间,mm_struct,虚拟内存,进程)