一文讲解,Linux内核——内存管理(建议收藏)

【推荐文章】

浅谈linux 内核网络 sk_buff 之克隆与复制

深入linux内核架构--进程&线程

了解Docker 依赖的linux内核技术

怎么在Windows下使用Makefile文件

浅析linux内核网络协议栈--linux bridge

一.内存的基础知识:

1.写程序到程序运行的过程:

(1)编译:由编译程序将用户代码编译成若干个目标模块(把高级语言翻译成机器语言)

(2)链接:由链接程序将编译后形成的一组目标模块以及所需的函数链接在一起,形成一个完整的模块

(3)装入:由装入程序将装入模块装入到内存运行。

2.链接的三种方式:

(1)静态链接:装入前链接成一个完整的装入模块

(2)装入时动态链接:运行前变装入边链接

(3)运行时动态装入:运行时目标模块才装入并链接

3.装入的三种方法:

(1)绝对装入:编译产生绝对地址。

(2)可重定位装入:装入时将逻辑地址转为物理地址。

(3)动态运行时装入:运行时将逻辑地址转为物理地址,需设置重新定位寄存器。

二.内存管理的基本概念

地址转换:操作系统负责实现逻辑地址到物理地址的转换。

存储保护:保证各进程在自己的内存空间内运行,不会越界访问。两种实现方式:设置上下限寄存器和利用重定位寄存器界地址寄存器进行判断。

三.覆盖与交换

1.覆盖技术:

思想:将程序分成多个段(多个模块)。不可能同时被访问程序段共享一个覆盖区,覆盖区中的程序段在运行的过程中会根据需要调入调出。

2.交换技术:

思想:内存空间紧张的时候,系统将内存中的某些进程暂时换出外存,把外存中的某些已具备运行条件的进程换入内存(进程在内存与磁盘间的动态调度)。暂时换出外存等待的进程状态为挂起状态。

(1)具有交换功能的操作系统中,通常把磁盘空间分为文件区和对换区两部分。文件区主要用于存放文件,采用离散分配的方式;对换区空间只占磁盘的小部分,被换出的进程就放在对换区。对换区采用连续分配方式。兑换区的I/O速度比文件区的更快。

(2)交换通常在许多进程吃紧且内存吃紧时进行。

(3)可优先换出阻塞进程;可换出优先级较低的进程(PCB会常驻内存,不会被换出外存)。

3.覆盖与交换的区别:覆盖是在同一个程序或者进程中,交换是在不同的进程(或作业)之间的。

四.连续分配管理方式

1.单一连续分配:

内存被分为系统区和用户区,系统区通常位于内存的低地址部分,用于存放操作系统的数据,用户区用于用户进程的相关数据。内存中只能有一道程序,用户程序独占整个用户空间。

(1)优点:实现简单,无外部碎片,可以用覆盖技术扩充内存。

(2)缺点:只能用于单用户,单任务的操作系统中,有内部碎片,存储器利用率极低。

2.固定分区分配:

将用户空间分为若干个固定大小的分区,在每个分区中知装入一道作业。又分为分区大小相等和分区大小不等的。

分区大小相等的:缺乏灵活性,适合于一台计算机控制多个相同的对象的场合。

分区大小不等的:增加了灵活性,可以满足不同大小进程的需求。

操作系统需要建立一个数据结构——分区说明表,来实现各个分区的分配和回收。

(1)优点:实现简单,无外部碎片。

(2)缺点:当用户程序太大时,所有的分区都不能满足需求。会产生内部碎片。

3.动态分区分配(又称可变分区分配):

不会预先划分内存分区,根据进程的大小动态的建立分区,并使分区的大小正好适合进程的需要,系统分区的大小和数目是可变的。

两种常用的数据结构:空闲分区表和空闲分区链

动态分区分配没有内部碎片,但是有外部碎片。

内部碎片:分配给某进程的内存区域中,有些部分没有用上。

外部碎片:是指内存中的某些空闲分区由于太小而难以利用。

五.动态分区分配算法

1.首次适应算法:

(1)算法思想:每次都从低地址开始查找,找到一个能满足大小的空闲分区。

(2)实现:空闲分区以地址递增的次序排列,每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。

2.最佳适应算法

(1)算法思想:为保证大进程到来的时候有连续的大片空间,可以尽可能的留下大片的空闲区,优先使用更小的空闲区。

(2)实现:空闲分区按容量递增的次序链接,每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能够满足要求的第一个空闲分区。

(3)缺点:每次都选最小的分区进行分配,会留下越来越多的,很小的,难以利用的内存块,会产生很多的外部碎片。

3.最坏适应算法

(1)算法思想:为解决最坏适应算法的问题。可以在每次分配的时候优先使用最大的连续空闲区,这样剩余的空闲区就不会太小,更方便使用。

(2)实现:空闲分区按容量递减次序链接,每次分配内存时顺序查找空闲分区链(或者空闲分区表),找到大小能够满足要求的第一个空闲分区。

(3)缺点:每次选最大的分区进行分配,会导致较大的连续的空闲区被迅速用完,如果有大进程到达,就没有内存分区可用了。

4.邻近适应算法

(1)算法思想:每次都从上次查找结束的位置开始检索。

(2)实现:空闲分区以地址递增的顺序排列(可排成一个循环链表),每次分配内存时从上次查找结果的位置开始查找空闲分区链(或空闲分区表),找到大小满足要求的第一个空闲分区。

(3)缺点:会使高地址的大分区被用完。

六.基本分页存储管理的基本概念

1.分页存储的概念:

将内存分为一个个大小相等的区,每一个分区就是一个页框(页框=页帧=内存块=物理块=物理页面),每一个页框有一个编号,即页框号,页框号从0开始。

将进程的逻辑地址分为与页框大小相等的一个个部分,每个部分称为一个页或者页面,每个页面有一个编号,即页号,从0开始。

如何确定一个逻辑地址所对应的页号,页内偏移量:

如果每个页面的大小为2^kB,用二进制数表示逻辑地址,则末尾k位即为页内偏移量,其余部分就是页号。

一文讲解,Linux内核——内存管理(建议收藏)_第1张图片

每个页表项占的字节数:

一文讲解,Linux内核——内存管理(建议收藏)_第2张图片

如何实现地址的转换:

(1)计算出逻辑地址对应的页号和页内偏移量

(2)找到对应页面在内存中的存放位置

(3)物理地址=页面起始地址+页内偏移量

七.基本地址变换机构(用于实现逻辑地址到物理地址的转换的一组硬件结构)

基本地址变换机构:通常在系统中设置一个页表寄存器,存放页表在内存中的起始地址F和页面长度M。进程未执行时,页表起始地址和页表长度存放在进程控制块PCB中,当进程被调用时,操作系统内核会把它们放到页表寄存器中。

逻辑地址到物理地址的转换过程如下:

(1)计算页号P和页内偏移量W(2)比较页号P和页表长度M若P>=M,则产生越界中断,否则继续执行。

(3)页表中页号P对应的页表项地址=页表起始地址F+页号P*页表项长度

(4)计算E=B*L+W,用得到的物理地址E去访问。

一文讲解,Linux内核——内存管理(建议收藏)_第3张图片

八.具有快表的地址转换机构:

1.快表和慢表

快表:又称联想寄存器(TLB),是一种访问速度比内存快很多的高速缓存,用来存放最近访问的页表项的副本。

慢表:内存中的页表常称为慢表。

2.引入快表后地址的变换过程:

(1)CPU给出逻辑地址,由某个硬件算得页号,页内偏移量,将页号和快表中的所有页号进行比较

(2)如果找到匹配的页号,说明要访问的页表项在快表中有副本,则直接取出该页对应的内存块号,再将内存块号与页内偏移量拼接形成物理地址,最后访问物理地址对应的内存单元。若在快表中,则访问某个逻辑地址仅需要一次访存即可。

(3)如果没有找到匹配的页号,则需要访问内存中的页表,找到对应的页表项,得到页面存放的内存块号,再将内存块号与业内偏移量拼接成物理地址,最后,访问该物理地址对应的内存单元,因此,若快表未命中,则访问某个逻辑地址需要两次访存。

3.TLB和Cache的区别:

TLB中只有页表项的副本,而普通的Cache中可能会有其他的各种数据的副本。

九.两级页表:

1.解决单级页表的问题:

将长长的页表进行分组,使每个内存块刚好可以放入一个分组,为离散分配的页表建立一张页表,称为页目录表或顶层页表。

2.实现地址变换的过程:

(1)将逻辑地址结构分为三部分

(2)从PCB中读出页目录表地址,再根据一级页号查页目录表,找到下一级页表在内存中的存放位置

(3)根据耳机页号查表,找到最终的访问内存块号

(4)结合页内偏移量找到物理地址

一文讲解,Linux内核——内存管理(建议收藏)_第4张图片

注:(1)多级页表中,各级页表的大小不能超过一个页面,若两级页表不够,可以分更多级。

​ (2)多及页表的访存次数(没有快表),N级页表访存次数为N+1次访存。

十.基本分段存储管理:

1.分段的基本概念

(1)将空间地址按照程序自身的逻辑关系划分为若干个段,每段从0开始编址。

(2)每个段在内存中占连续的单元,但各段之间可以不相邻

(3)逻辑地址结构:段号+段内地址

2.段表:

每个段对应一个段表项,各段表项长度相同,由段号,段长,基地址组成,记录逻辑段到实际存储地址的映射关系。

3.地址变换:

(1)由逻辑地址得到段号,段内地址

(2)段号与段表寄存器中的段长度作比较,检查是否越界

(3)由段表始址,段号找到对应的段表项

(4)根据段表中记录的段长,检查段内地址是否越界

(5)由段表中的基地址+段内地址得到最终的物理地址

(6)访问目标单元

4.分页和分段的对比:

(1)分页对用户不可见,分段对用户可见

(2)分页的地址空间是一维的,分段的空间地址是二维的

(3)分段更容易实现信息的共享和保护

(4)分页(单级页表),分段访问一个逻辑地址都需要两次访存,分段存储中也可以引入快表机构

十一.段页式管理方式:

1.基本概念:(分段+分页)

(1)将地址空间按照程序的自身的逻辑关系划分为如干个段,再将各段分为大小相等的页面。

(2)将内存空间分为与页面大小相等的一个个内存块,系统以块为单位为进程分配内存

2.页表和段表:

(1)每一个段对应一个段表项。各段表项长度相同,由段号(隐含),页表长度,页表存放地址组成。

(2)每一个页对应一个页表项。若页表项长度相同,由页号(隐含),页面存放的内存块号组成。

一文讲解,Linux内核——内存管理(建议收藏)_第5张图片

3.地址变换的过程:

(1)由逻辑地址得到段号,页号,页内偏移量

(2)段号与段表寄存器中的段长度进行比较,检查是否越界

(3)由段表始址,段号找到对应的段表项

(4)根据段表中记录的页表长度,检查页号是否越界

(5)由段表中的页表地址,页号得到查询页表,找到相应的页表项

(6)由页表存放的内存块号,页内偏移量得到最终的物理地址

(7)访问目标单元

4.访问一个逻辑地址所需的访存次数:第一次查段表,第二次查页表,第三次访问目标单元

十二.虚拟内存:

1.传统的存储管理方式的特征:

(1)一次性:作业数据必须一次全部调入内存。(2)驻留性:作业数据在整个运行期间都会常驻内存

2.局部性原理:

(1)时间局部性:现在访问的指令,数据在不久后很可能会被再次访问

​ (2)空间局部性:现在访问的内存单元周围的内存空间,很可能不久后会访问

​ (3)空间缓存技术:使用频繁的数据放到更高速的存储器中

3.虚拟内存的定义及其特征:

程序不需要全部装入即可运行,运行的时候根据需要动态调入数据,若内存不够,还需要换出一些数据。

特征:(1)多次性:无需在作业运行时一次全部装入内存,而是允许被分成多次调入内存的。

​ (2)对换性:无需在作业运行时一直常驻内存,而是允许在作业运行的过程中,将作业换入,换出。

​ (3)虚拟性:从逻辑上扩充了内存的容量,使用用户看到的内存容量,远大于实际的容量。

4.虚拟内存技术的实现:

(1)访问的信息不在内存时,由操作系统系统负责将所需的信息从外存调入内存(请求调页功能)

(2)内存空间不够时,将内存中的暂时用不到信息换出到外存(页面置换功能)

(3)虚拟内存的实现:请求分页存储管理,请求分段存储管理,请求段页式存储管理

十三.请求分页管理方式:

1.页表机制:

在基本分页的基础上增加了几个表项

(1)状态位:表示页面是否在内存当中

(2)访问字段:记录最近被访问的次数,或记录上次访问的时间

(3)修改位:表示页面调入内存后是否被修改过,只有修改过的页面才需要在置换时写回外存

(4)外存地址:页面在外存当中的存放位置

2.缺页中断机构:

(1)找到页表项后检查页面是否已在内存中,若没在,产生缺页中断

(2)缺页中断处理中,需要将目标页面调入内存中,有必要时还需要换出页面

(3)缺页中断属于内中断,属于内中断中的故障,即可能被系统修复的异常

(4)一条指令在执行的过程中可能产生多次缺页中断

3.地址变换与基本分页的不同之处:

(1)找到页表项是需要检查页面是否在内存中

(2)若页面不在内存中,需要请求调页

(3)若内存空间不够,还需要换出页面

(4)页面调入内存后,需要修改相应的页表项

十四.页面置换算法:

1.最佳置换算法(0PT):

2.先进先出置换算法(FIFO):

3.最近最久未使用置换算法(LRU):

4.时钟置换算法( CLOCK):

一文讲解,Linux内核——内存管理(建议收藏)_第6张图片

十五.页面分配策略

1.驻留集:指请求分页存储管理中给进程分配的内存块的集合

2.页面分配,置换策略:

(1)固定分配和可变分配:区别在于运行进程期间驻留集大小是否可变

(2)局部置换和全局置换:区别在于发生缺页时是否只能从进程自己的页面中选择一个换出

(3)固定分配局部置换:进程运行前就分配一定数量的物理块。缺页时只能换出进程自己的某一页

(4)可变分配全局置换:只要缺页就分配新的物理块,可能来自空闲物理块,也可能换出别的进程的页面

(5)可变分配局部置换:频繁缺页的进程,多分配一些物理块;缺页率很低的进程,回收一些物理块,知道缺页率合适

3.调入页面的时机:(1)预调页策略:进程运行前(2)请求调页策略:进程运行时,发现缺页再调页

4.从何处调页:

(1)对换区:采用连续存储方式,速度快。文件区:采用离散存储方式,速度更慢。

(2)对换区足够大:运行将数据从文件区复制到对换区,之后所有的页面调入,调出都是在内存与对换区之间进行。

(3)对换区不够大:不会修改的数据每次都从文件区调入,会修改的数据调出到对换区,需要时再从对换区调入

(4)UNIX的方式:第一次使用的页面都从文件区调入,调出的页面都写回对换区,再次使用从对换区调入

5.抖动(颠簸)现象:页面频繁换入换出的现象,主要原因是分配给进程的物理块不够。

6.工作集:在某段时间间隔内,进程实际访问的页面的集合,驻留集大小一般不能小于工作集的大小。

知道缺页率合适

3.调入页面的时机:(1)预调页策略:进程运行前(2)请求调页策略:进程运行时,发现缺页再调页

4.从何处调页:

(1)对换区:采用连续存储方式,速度快。文件区:采用离散存储方式,速度更慢。

(2)对换区足够大:运行将数据从文件区复制到对换区,之后所有的页面调入,调出都是在内存与对换区之间进行。

(3)对换区不够大:不会修改的数据每次都从文件区调入,会修改的数据调出到对换区,需要时再从对换区调入

(4)UNIX的方式:第一次使用的页面都从文件区调入,调出的页面都写回对换区,再次使用从对换区调入

5.抖动(颠簸)现象:页面频繁换入换出的现象,主要原因是分配给进程的物理块不够。

6.工作集:在某段时间间隔内,进程实际访问的页面的集合,驻留集大小一般不能小于工作集的大小。

你可能感兴趣的:(linux,java,运维)