Linux内存管理——段页式访问

Posted 正在起飞的蜗牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux内存管理——段页式访问相关的知识,希望对你有一定的参考价值。

1、早期的内存管理方式

1.1、管理方式介绍

(1)早期的程序都是直接运行在物理内存上,程序访问的都是物理地址,根本没有虚拟地址的概念;
(2)如果计算机同时只运算一个程序,只要程序需要的内存空间不超过实际物理内存空间的大小,则程序可以正常运行;
(3)如果计算机同时运行多个程序,不仅要求多个程序加起来需要的内存空间小于实际物理空间的大小,而且程序要求分配到的物理内存必须要连续;

1.2、实际举例

(1)假如物理内存有130M, 现在A程序需要10M内存,B程序需要100M内存,C程序需要20M内存。
(2)我们先运行A程序再运行B程序,此时物理内存还剩下20M,如果接下来再运行C程序,因为C程序需要30M内存,此时剩下的物理内存是不够的。
(3)如果按照纯数学计算,我们只需要把A程序换出,刚好空闲30M内存;
(4)但是实际这样行不通,因为C程序要求连续的30M内存空间,解决办法只有把100M的B程序换出到外存,很明显这样的效率很低,内存管理方式很粗糙;

1.2、缺点

(1)地址空间不隔离:所有程序都是访问的物理地址,恶意程序可以去访问没有分配分配给它的内存空间,从而导致其他程序崩溃。或者是程序本身有bug,不小心访问其他程序分配到的物理空间,结果就是一个程序崩溃导致全部程序崩溃;
(2)内存使用效率低:从上面举例就可以看出来内存效率使用低,并且存在大量的换入换出的情况;
(3)程序运行的地址不确定:代码分为位置无关码和位置有关码,对于位置有关码是必须要求程序运行在链接地址处的。由于每次分配到的物理地址都不确定,给编程带来了麻烦,这涉及到代码重定位的问题。
补充:参考博客:《代码重定位》《位置有关码和位置无关码》

2、分段式内存管理方式

2.1、分段式管理介绍

(1)分段管理的思想:把程序需要的内存空间大小的虚拟地址映射到一段同等大小的物理内存地址空间;
(2)假设有A程序需要10MB(0x00000000-0x00B00000)的内存大小,程序B需要100MB(0x00000000-0x06400000)的内存大小;
(3)按照分段式映射后,虚拟空间和物理空间的映射关系如上图;
(4)程序A和程序B在代码中都是从虚拟地址的0x0地址开始去访问,至于虚拟地址到物理地址的转换由操作系统去完成;
(5)比如:程序A访问0x00001000地址,实际访问的是物理地址的0x00101000;

分段式管理的优缺点

(1)优点:解决了地址不隔离运行地址不确定这两个问题,但是没有解决内存效率使用不高的问题;
(2)缺点:分段的方式对内存管理的单位太粗糙,每个程序需要的内存段大小都不同,对内存划分的颗粒度太大,导致有大量的数据需要换入换出,内存使用效率很低;

3、分页式内存管理方式

3.1、分页式内存管理的理论基础

(1)之前介绍的内存管理方式都是将程序一次性全部装载进内存,但是根据程序的局部性原理(即在一段时间内,整个程序的执行仅限于程序中的某一部分),我们没有必要一次性全部加载,我们只需要加载近期会用到的部分程序就可以正常运行;
(2)分段式管理方式已经引入了虚拟地址到物理地址的转换,但是每个程序段的大小不确定,并且段要求映射到连续的物理内存,这导致频繁的换入换出,内存使用效率低;
(3)我们结合上面两点:把虚拟地址到物理地址的映射单位从不确定的段大小改为确定的页大小;根据程序局部性原理,只把近期要用到的部分程序加载到内存,暂时未用到的部分还是在外存中,将来用到时发生缺页中断,再加载到内存中;

3.2、虚拟地址到物理地址的转换

(1)几乎所有的CPU都采用了MMU(Memory Management Unit:内存管理单元)来进行虚拟地址到物理地址的转换;
(2)MMU现在都是集成到CPU的内部,ARM架构的CPU中由协处理器来控制MMU单元;
(3)在uboot或者内核的启动阶段,设置号转换页表,后续程序使用虚拟地址访问内存时,MMU会自动转换成物理地址,上层的程序不用关心地址转换问题;
补充:参考博客:《嵌入式开发(S5PV210)——u-boot中开启MMU》

3.3、分页式内存管理分析

(1)假设有进程process 1和process 2,两个进程都有8个页大小的虚拟地址空间,有的页映射到物理内存,有的页映射到磁盘空间;
(2)虚拟页(VP,virtual page),物理页(PP,physical page),磁盘页(DP,disk page);
(3)物理内存也是8个页,这不是巧合。按照分页式管理,每个进程都认为自己是独享内存的,所以物理内存有多少个页进程的虚拟内存就有多少个页,只是有的页能映射到物理内存,有的页被映射到磁盘空间;
(4)按照上面的映射关系,访问进程1的虚拟页vp7,就是访问物理内存的pp3页,具体虚拟页到物理页的转换由MMU完成,以此类推;
(5)进程1的vp7和进程2的vp7同时映射到物理页pp3,这种情况下就共享物理页。比如pp3页是存放的共享库,或者是存放的某个文件,并且运行多进程同时操作;
(6)进程1的vp3和vp2页映射到磁盘的dp1和dp0,当进程去访问vp3或vp2时,就会发生缺页中断,将磁盘的dp1和dp0换到物理内存中;如果物理内存已经没有多余的页,则会根据算法将某些暂时用不到的物理页先换到磁盘中,腾出空间来将磁盘中新的页换进来;

3.4、分页式内存管理总结

(1)分页的大小要根据硬件来决定,使得硬件的访问效率更高,现在常用的页大小是4KB,也有1MB、4MB的大小;
(2)同一时间操作系统只能选择一种页大小,所以无论哪个时刻操作系统的页大小是确定的;但是在不同时刻,同一操作系统的页大小可能不同;比如:在uboot启动阶段,会建立1MB大小的粗页表,在系统的启动后续阶段再建立4KB大小的细页表;
(3)操作系统会建立页表来管理页,可以在页表中设置页的权限属性,页表又分为一级页表和二级页表;比如:哪些进程可以访问这个页,哪些进程可以修改这个页;

以上是关于Linux内存管理——段页式访问的主要内容,如果未能解决你的问题,请参考以下文章

Linux内存管理——段页式访问

:内存管理 -- 非连续分配管理方式:基本分段存储管理方式段页式管理方式

存储管理-段页式管理

Windows内存管理和linux内存管理

linux内存管理--linux内核高端内存

linux内核源码——内存管理:段页式内存及swap