操作系统:内存管理详解

来源:互联网 发布:js动态添加删除表格行 编辑:程序博客网 时间:2024/06/05 17:26

操作系统连接着计算机的底层硬件与上层应用软件,控制着其他程序的运行,并且管理系统相关资源,同时提供配套的系统软件支持。

· 内存管理的几种方式?
· 分段和分页的区别?
· 什么是虚拟内存?
· 什么是内存碎片?
· 虚拟地址逻辑地址线性地址物理地址有什么区别?
· Cache替换算法有哪些?

内存管理的几种方式

常见的内存管理方式有块式管理,页式管理,段式管理和段页式管理。

(1)块式管理:把主存分为一块一块,当所需的程序片段不在主存时就分配一块主存空间,把程序片段载入主存,就算所需的程序片段只有几个字节也只能把这一块分配给它。这样会造成很大的浪费,平均浪费了50%的内存空间,但是易于管理。
(2)页式管理:把主存分为一页一页的,每一页的空间比一块块的空间小很多,虚拟地址空间被划分为一个一个固定大小的块(称作虚页),同时也让实际地址空间也划分为一个一个同样大小的页(称作实页),这种方式的主存空间利用率比块式管理高很多。

优点: a.主存储器的利用率比较高 b.页表相对比较简单 c.地址变换的速度比较快 d.对磁盘的管理比较容易
缺点:a.程序的模块化性能不好 b.页表很长,需要占用很大的存储空间

(3)段式管理:把主存分为一段段的,每一段的空间又比一页页的空间小很多,这种方法的空间利用率要比页式管理高得多,但是也有缺点。一个程序段可能会被分为几十段,这样时间可能就会被浪费在计算每一段的物理地址上。
(4)段页式管理:结合了段式管理和页式管理的有点。把主存先分成若干段,每段又分成若干页。段页式管理每取一次数据需要访问三次以上内存。虽然访问次数多,但是效率很高。

这里写图片描述

第一次是由段表地址寄存器得段表始址后访问段表,由此取出对应段的页表在内存中的地址。
第二次是访问页表得到所要访问的物理地址。
第三次才是访问真正需要访问的物理单元。

分段和分页的区别是什么

页是信息的物理单位,分页是为了实现离散分配方式,以削减内存的外零头,提高内存利用率;或者说分页仅仅是由于系统管理的需要,认不是用户的需要。
段是信息的逻辑单位,它含有一组其意义想对完整的信息。分段的目的是为了更好而满足用户的需要。页的大小是固定且由系统确定的,把逻辑地址划分为页号和页内地址两部分,由机器硬件实现,因此一个系统只能有一种大小的页面。段的长度却不固定,取决于用户所编写的程序,通常由编译程序在对原程序进行编辑时,根据信息的性质来划分。
分页的作业地址空间是一维的,即单一的线性空间,程序员只需用一个记忆符即可表示一个地址。分段作业地址空间是二维的。程序员在标致一个地址前,程序员在标识一个地址时 既需要给出段名,有需要给出段内存地址。

简单总结记忆:页信息–物理单位–一维 段信息–逻辑单位–二维

比如,在等长固定分区中,进程装入一个分区后,若这个分区还有没用的部分,则这个部分叫做内零头
再比如,可变分区时,可能会形成大量较小的,难以再分配的分区这样分区叫外零头

什么是虚拟内存

虚拟内存简称虚存,是计算机系统内存管理的一种技术。它是相对于物理内存而言的,可以理解为“假的内存”。它使得应用程序认为它拥有连续的可用的内存,允许程序员编写比实际系统拥有的内存大得多的程序,这使得许多大型软件项目能够在具有有限内存资源的系统上实现。而实际上,他通常被分割成许多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要的时候进行数据交换。虚存比实存有以下好处:

(1)扩大地址空间。无论段式虚存,还是页式虚存,寻址空间都比实存大。

寻址空间一般指的是CPU对于内存寻址的能力。通俗地说,就是能最多用到多少内存的一个问题。

(2)内存保护。每个进程运行在各自的虚拟内存地址空间,互相不干扰对方。另外,虚存还对特定的内存地址提供写保护,可以防止代码或数据被恶意篡改

(3)公平分配内存。采用虚存之后,每个进程都相当于有太阳大小的虚存空间。

(4)当进程需要通信时,可采用虚存共享的方式实现。

不过,使用虚存也是有代价的,主要表现为以下几个方面:

(1)虚存的管理需要建立很多的数据结构,这些数据结构要占用额外的内存
(2)虚拟地址到物理地址的转换,增加了指令的执行时间
(3)页面的换入换出需要磁盘I/O,这是很耗时间的。
(4)如果一页中只有一部分数据,会浪费内存。

什么是内存碎片

内部碎片的产生:因为所有的内存分配必须起始于可被 4、8 或 16 整除(视 处理器体系结构而定)的地址或者因为MMU的分页机制的限制,决定内存分配算法仅能把预定大小的内存块分配给客户。假设当某个客户请求一个 43 字节的内存块时,因为没有适合大小的内存,所以它可能会获得 44字节、48字节等稍大一点的字节,因此由所需大小四舍五入而产生的多余空间就叫内部碎片。
外部碎片的产生: 频繁的分配与回收物理页面会导致大量的、连续且小的页面块夹杂在已分配的页面中间,就会产生外部碎片。假 设有一块一共有100个单位的连续空闲内存空间,范围是0~99。如果你从中申请一块内存,如10个单位,那么申请出来的内存块就为0~9区间。这时候你 继续申请一块内存,比如说5个单位大,第二块得到的内存块就应该为10~14区间。如果你把第一块内存块释放,然后再申请一块大于10个单位的内存块,比 如说20个单位。因为刚被释放的内存块不能满足新的请求,所以只能从15开始分配出20个单位的内存块。现在整个内存空间的状态是0~9空闲,10~14 被占用,15~24被占用,25~99空闲。其中0~9就是一个内存碎片了。如果10~14一直被占用,而以后申请的空间都大于10个单位,那么0~9就 永远用不上了,变成外部碎片。

虚拟地址、逻辑地址、线性地址、物理地址有什么区别

虚拟地址是指由程序产生的由段选择符和段内偏移地址组成的地址。这两部分组成的地址并没有直接访问物理内存,而是要通过分段地址的变换处理后才会对相应到相应的物理内存地址。

逻辑地址指由程序产生的段内偏移地址。有时把逻辑地址当成虚拟地址,两者并没有明确的界限。

线性地址是指虚拟地址到物理地址变换的中间层,是处理器可寻址的内存空间(成为线性地址空间)中的地址。程序代码会产生逻辑地址,或者说是段中偏移地址,加上相应段基址就生成了一个线性地址。如果启用了分页机制,那么线性地址可以再经过变换产生物理地址。若没有产生分页机制,那么线性地址就是物理地址。

物理地址是指限制cpu外部地址总线上的寻址物理内存的地址信号

数据总线

(1) 是CPU与内存或其他器件之间的数据传送的通道。
(2)数据总线的宽度决定了CPU和外界的数据传送速度。
(3)每条传输线一次只能传输1位二进制数据。eg: 8根数据线一次可传送一个8位二进制数据(即一个字节)。
(4)数据总线是数据线数量之和。

地址总线
(1)CPU是通过地址总线来指定存储单元的。
(2)地址总线决定了cpu所能访问的最大内存空间的大小。eg: 10根地址线能访问的最大的内存为1024位二进制数据(1B)
(3)地址总线是地址线数量之和。

控制总线
(1)CPU通过控制总线对外部器件进行控制。
(2)控制总线的宽度决定了CPU对外部器件的控制能力。
(3)控制总线是控制线数量之和。

虚拟地址到物理地址的转化方法是与体系结构相关的,一般有分段与分页两种方式。以x86的CPU为例,分段和分页都是支持的。内存管理单元负责从虚拟地址到物理地址的转换。逻辑地址是标识+段内偏移量的形式,MMU(内存管理单元)通过查询段表,可以把逻辑地址转化成线性地址。如果CPU没有开启分页功能,那么线性地址就是物理地址;如果开启了,那么MMU还需要查询页表来将线性地址转化为物理地址:逻辑地址(段表)–>线性地址(页表)–>物理地址。
映射是一种多对一的关系,即不同的逻辑地址可以映射到同一个线性地址上;不同的线性地址也可以映射到同一个物理地址上。而且,同一个线性地址在发生换页以后,也可能被重新装载到另外一个物理地址上,所以这种多对一的映射关系也会随时间发生变化。

Cache替换算法有哪些

数据可以存放在CPU或者内存中。CPU处理快,但是容量小;内存容量大,但是转交给CPU处理的速度慢。为此需要Cache(缓存)来做一个折中。最有可能的数据先从内存调入Cache,CPU再从Cache读取数据,这样会快许多。然而,Cache中所存放的数据不是100%有用的。CPU从Cache中读取到有用的数据成为“命中”。

Cache替换算法有随机算法、FIFO算法、LRU算法、LFU算法和OPT算法。
(1)随机算法。随机算法就是用随机数发生器产生一个要替换的块号,将该块替换出去,此算法简单、易于实现,而且它不考虑Cache块过去、现在及将来的使用情况。但是由于没有利用上层存储器使用的“历史信息”、没有根据访存的局部性原理,故不能提高Cache的命中率,命中率较低。

(2)先进先出(FIFO)算法。先进先出(First In First Out,FIFO)算法是将最先进入Cache的信息块替换出去。FIFO算法按调入Cache的先后决定淘汰的顺序,选择最早调入Cache的字块进行替换,它不需要记录各字块的使用情况,比较容易实现,系统开销小,其缺点是可能会把一些需要经常使用的程序可(如循环程序)也作为最早进入Cache的块替换掉,而且没有根据访存的局部性原理,故不能提高Cache的命中率。因为最早调入的信息可能以后还要用到,或者经常要用到,如循环程序。此法简单、方便,利用了主存的“历史信息”,但并不能说最先进入的就不经常使用,其缺点是不能正确反映程序局部性原理,命中率不高,可能出现一种异常现象。

(3)近期最少使用(LRU)算法。近期最少使用(Least Recently Used,LRU)算法是将近期最少使用的Cache中的信息块替换出去。该算法较先进先出算法要好一些,但此法也不能保证过去不常用将来也不常用。
LRU算法是依据各块使用的情况,总是选择那个最近最少使用的块被替换。这种方法虽然比较好地反映了程序局部性规律,但是这种替换方法需要随时记录Cache中各块的使用情况,以便确定哪个块是近期最少使用的块。LRU算法相对合理,但实现起来比较复杂,系统开销较大。通常需要对每一块设置一个称为计数器的硬件或软件模块,用以记录其被使用的情况。

实现LRU策略的方法有很多种。简单介绍计数器法、寄存器栈法及硬件逻辑比较对法的设计思路。

计数器法:缓存的每一块都设置一个计数器。计数器的操作规则如下:

被调入或者被替换的块,其计数器清0,而其他的计数器则加1
当访问命中时,所有块的计数值与命中块的计数值要进行比较,如果计数值小于命中块的计数值,则该块的计数值加”1”;如果块的计数值大于命中块的计数值,则数值不变。最后将命中块的计数器清为“0”
需要替换时,则选择计数值最大的块被替换。
(4)最优替换算法(OPT算法)。使用最优替换算法(OPTimal replacement Algorithm)时必须先执行一次程序,统计Cache的替换情况。有了这样的先验信息,在第二次执行该程序时便可以用最有效的方式来替换,以达到最优的目的。

前面介绍的几种页面替换算法主要是以主存储器中页面调度情况的历史信息为依据的,它假设将来主存储器中的页面调度情况与过去一段时间内主存储器中的页面调度情况是相同的,显然,这种假设不总是正确的。最好的算法应该是选择将来最久不被访问的页面作为被替换的页面,这种替换算法的命中率一定是最高的,它就是最优替换算法。

要实现OPT算法,唯一的办法是让程序先执行一遍,记录下实际的页地址流情况。根据这个页地址流才能找出当前要被替换的页面。显然,这样做是不现实的。因此,OPT算法只是一种理想化的算法,然而它也是一种很有用的算法。实际上,经常把这种算法用来作为评价其他页面替换算法好坏的标准。在其他条件相同的情况下,哪一种页面替换算法的命中率与OPT算法最接近,那么它就是一种比较好的页面替换算法。

(5)最少使用算法(LFU算法 Least Frequently Used Algorithm)。选择最少访问的页面作为被替换的页面。显然,这是一种合理的算法,因为到目前为止最少使用的页面,很可能是将来最少访问的页面。该算法既充分利用了主存中页面调度情况的历史信息,又正确反映了程序的局部性。但是,这种算法实现起来非常困难,它要为每个页面设置一个很长的计数器,并且要选择一个固定的时钟为每个计数器定时计数。在选择被替换页面时,要从所有计数器中找出一个计数器值最大的计数器。

0 0
原创粉丝点击