一、进程地址空间
程序本身不占内存,只有运行起来后,被加载到内存中,才占据空间。
因此程序地址空间,更应该称为进程地址空间。
空间分布:
二、虚拟地址空间
1.虚拟地址空间简介
事实上,进程内部我们所访问到的空间的地址都是一个假地址,因为进程地址空间其实是一个虚拟地址空间,进程中使用的地址都是虚拟地址空间中的地址。
2.为什么使用虚拟地址空间?★
操作系统通过虚拟地址空间告诉每个进程都拥有一个完整大小的空间,但实际上是每个进程用多少空间,才分配多少空间,并且访问的是虚拟地址;通过在物理与虚拟之间建立一个映射关系,这样就可以做到虚拟访问的地址与实际地址不同,从而可以离散存储数据,合理利用内存的碎片空间。
★使用虚拟地址空间的作用:
进程使用的是一个完整的,线性的虚拟地址,不用担心与其他进程地址冲突;并且经过页表映射后,数据在物理内存中可以离散存储,提高内存利用率;并且在页表映射这里可以进行内存访问控制。
3.虚拟地址空间的本质&实现
本质&实现:
虚拟地址空间即在虚拟的空间维度,对空间进行了划分,由操作系统为每个进程虚拟描述的一个地址空间。
或者说,虚拟地址空间就是系统为进程进行的虚拟空间维度的划分描述,在linux下这个描述是一个mm_struct结构体。
4.写时拷贝技术
原理:原本访问的是同一块空间,但是当空间中数据要发生改变时,就要为子进程重新开辟空间,将数据拷贝进去,并修改映射关系。
示例:
如图所示,进程通过页表内的映射关系,从而将虚拟地址空间映射到物理内存。
同时,因为子进程创建时,会复制父进程pcb中的大部分信息,那么如图若父进程内部有一个变量val,那么子进程也会有一个val,且两者所指向的是同一块内存空间,但是这块内存是属于父进程的。
那如果此时子进程要修改这个变量,会发生什么?
因为该内存是属于父进程的,所以当子进程要修改时,系统就会为子进程重新开辟空间,将数据拷贝进去,并修改映射关系。这就是写时拷贝技术,也说明为什么有时候同一个地址,但是却有不同的值的原因。
三、内存管理方式(映射方式)
1.分段式内存管理
原理:
将虚拟地址空间进行分段,代码段、数据段......
作用:
便于编译器进行地址管理(一个程序中的数据所用的地址除了动态申请之外,其实都是在编译完成后就确定了)。
实现:
将虚拟地址空间进行分段,而虚拟地址包含两个信息:段号,段内偏移
物理块起始地址+段内偏移=实际存储地址
示例:
2.分页式内存管理
原理:
将虚拟地址空间进行了更加细致的分页管理,一个内存页默认4096个字节。
实现:
将虚拟地址空间进行分页;虚拟地址组成:页号,页内位移
物理起始地址+页内偏移=物理存储地址
示例:
与分段式不同的是,分页式在找到物理存储地址后,会判断是否具有操作权限,是否触发缺页中断。
作用:
分页式划分更加细致,主要实现数据经过页表映射后,在物理内存上的离散存储,提高内存利用率,并且在页表映射中进行内存访问控制。
3.段页式内存管理
原理:
将地址空间进行分段,每个段内采用分页管理。
虚拟地址组成:段号+段内页要+页内偏移
实现:
通过段号找到段表项,段表项中记录了对应段的页表位置,找到页表,然后通过段内页号,找到页表中的页表项,通过页表项中的物理块地址+页内偏移-->实际存储地址。
相当于结合利用了分段式和分页式各自的优点。
四、缺页中断&内存置换
1.缺页中断
发现当前要访问的数据不在物理内存中,触发缺页中断,将需要的数据从交换分区中重新加载进来。
2.内存置换
计算机上的设备内存条,其物理内存通常都不大,但是如果运行的程序多了,加载的数据太多,物理内存总会有不够用的时候,则将物理内存中(不常用)的数据取出来,放到磁盘的交换分区中存储,这个磁盘的交换分区被当作交换内存使用,腾出来的内存给新的程序使用。
何为不常用的数据?
由对应的置换算法所定义不常用的数据,例如:最近最久未使用LRU、最少未使用LFU等等。