对计算机系统而言,操作系统充当着基石的作用,它是连接计算机底层硬件与上层利用软件的桥梁,控制其他程序的运行,并且管理系统相干资源,同时提供配套的系统软件支持。对专业的程序员而言,掌握1定的操作系统知识比不可少,由于不管面对的是底层嵌入式开发,还是上层的云计算开发,都需要使用到1定的操作系统相干知识。
常见的内存管理方式有块式管理、页式管理、段式和段页式管理。
(1)块式管理:把主存分为1大块1大块的,当所需的程序片断不在主存时就分配1块主存空间,把程序片断load入主存,就算所需的程序片断只有几个字节也只能把这1块分配给它。这样会造成很大的浪费,平均浪费了50%的内存空间,但是易于管理。
(2)页式管理:把主存分为1页1页的,每页的空间要比1块1块的空间小很多,这类方法的空间利用率要比块式管理高很多
(3)段式管理:把主存分为1段1段的,每段的空间又要比1页1页的空间小很多,这类方法在空间利用率上又比页式管理高很多,但是也有另外1个缺点。1个程序片断可能会被分为几10段,这样很多时间就会被浪费在计算每段的物理地址上。
(4)段页式管理:结合了段式管理和页式管理的优点。把主存先分成若干段,每一个段又分成若干页。段页式管理每取1护具,要访问3次内存。
页是信息的物理单位,分页是为了实现离散分配方式,以消减内存的外零头,提高内存的利用率;或说,分页仅仅是由于系统管理的需要,而不是用户的需要。
段是信息的逻辑单位,它含有1组其意义相对完全的信息。分段的目的是为了能更好地满足用户的需要。页的大小固定且由系统肯定,把逻辑地址划分为页号和页内地址两部份,是由机器硬件实现的,因此1个系统只能有1种大小的页面。段的长度却不固定,决定于用户所编写的程序,通常由编译程序在对源程序进程编辑时,根据信息的性质来划分。
分页的作业地址空间是1维的,即单1的线性空间,程序员只需利用1个记忆符,便可表示1地址。分段的作业地址空间是2维的,程序员在标识1个地址时,既需给出段名,又需给出段内地址。
虚拟内存简称虚存,是计算机系统内存管理的1种技术。它是相对物理内存而言的,可以理解为“假的”内存。它使得利用程序认为它具有连续可用的内存(1个连续完全的地址空间),允许程序员编写并允许比实际系统具有的内存大很多的程序,这使得许多大型软件项目能够在具有有限内存资源的系统上实现。而实际上,它通常被分割成多个物理内存碎片,还有部份暂时存储在外部磁盘存储器上,在需要时进行数据交换。虚存比实存有以下好处:
(1) 扩大地址空间。不管段式虚存,还是页式虚存,或是段页式虚存,寻址空间都比实存大。
(2)内存保护。每一个进程运行在各自的虚拟内存地址空间,相互不能干扰对方。另外,虚存还对特定的内存地址提供写保护,可以避免代码或数据被歹意篡改
(3)公平分配内存。采取了虚存以后,每一个进程都相当于有太阳大小的虚存空间。
(4)当进程需要通讯时,可采取虚存同享的方式实现。
不过,使用虚存也是有代价的,主要表现在以下几个方面:
(1)虚存的管理需要建立很多数据结构,这些数据结构要占用额外的内存
(2)虚拟地址到物理地址的转换,增加了指令的履行时间
(3)页面的换入换出需要磁盘I/O,这是很耗时间的。
(4)如果1页中只有1部份数据,会很浪费内存。
内存碎片是由于屡次进行内存分配酿成的,当进行内存分配时,内存格式1般为:(用户使用段)(空白段)(用户使用段),当空白段很小的时候可能不能提供给用户足够需要的空间,可能夹在中间的空白段的大小为5,而用户需要的内存大小为6,这样会产生很多的间隙造成使用效力的降落,这些很小的空隙叫碎片。
内碎片:分配给程序的存储空间没有用完,有1部份是程序不使用,但其他程序也没法用的空间。内碎片是处于区域内部或页面内部的存储块,占有这些区域或页面的进程其实不使用这个存储块,而在进程占有这块存储块时,系统没法利用它,直到进程释放它,或进程结束时,系统才有可能利用这个存储块。。
由于空间太小,小到没法给任何程序分配(不属于任何进程)的存储空间是外碎片。外部碎片是处于任何已分配区域或页面外部的空闲存储块,这些存储块的综合可以满足当前申请的长度要求,但是由于它们的地址不连续或其他缘由,使得系统没法满足当前申请。
内碎片和外碎片是1对矛盾体,1种特定的内存分配算法,很难同时解决好内碎片和外碎片问题,只能根据利用特点进行取舍。。。
虚拟地址是指由程序产生的由段选择符合段内偏移地址组成的地址。这两部份组成的地址并没有直接访问物理内存,而是要通过分段地址的变换处理后才会对应到相应的物理内存地址。
逻辑地址指由程序产生的段内偏移地址。有时直接把逻辑地址当做虚拟地址,二者并没有明确的界限。。
线性地址是指虚拟地址到物理地址变换之间的中间层,是处理器可寻址的内存空间(称为线性地址空间)中的地址。程序代码会产生逻辑地址,或说是段中的偏移地址,加上相应段基址就生成了1个线性地址。如果启用了分页机制,那末线性地址可以再经过变换产生物理地址。若没有采取分页机制,那末线性地址就是物理地址。
物理地址是指限制CPU外部地址总线上的寻址物理内存的地址信号,是地址变换的终究结果。
虚拟地址到物理地址的转化方法是与体系结构相干的,1般有分段与分页两种方式。以x86CPU为例,分段分页都是支持的。内存管理单元负责从虚拟地址到物理地址的转化。逻辑地址是段标识+段内偏移量的情势,MMU(Memory Management Unit内存管理单元)通过查询段表,可以把逻辑地址转化为线性地址。如果CPU没有开启分页功能,那末线性地址就是物理地址;如果CPU开启了分页功能,MMU还需要查询页表来将线性地质转化为物理地址:逻辑地址(段表)-》线性地址(页表)-》物理地址。
映照是1种多对1的关系,即不同的逻辑地址可以映照到同1个线性地址上;不同的线性地址也能够映照到同1个物理地址上。而且,同1个线性地址在产生换页以后,也可能被重新装载到另外1个物理地址上,所以这类多对1的映照关系也会随时间产生变化。。
数据可以寄存在CPU或是内存中。CPU处理快,但是容量小;内存容量大,但是转交给CPU处理的速度慢。为此需要Cache(缓存)来做1个折衷。最有可能的数据先从内存调入Cache,CPU再从Cache读取数据,这样会快许多。但是,Cache中所寄存的数据不是100%有用的。CPU从Cache总读取到有用的数据称为“命中”。
Cache替换算法有随机算法、FIFO算法、LRU算法、LFU算法和OPT算法。
(1)随机算法(RAND)。随机算法就是用随机数产生器产生1个要替换的块号,将该块替换出去,此算法简单、易于实现,而且它不斟酌Cache块过去、现在及将来的使用情况。但是由于没有益用上层存储器使用的“历史信息”、没有根据访存的局部性原理,故不能提高Cache的命中率,命中率较低。
(2)先进先出(FIFO)算法。先进先出(First In First Out,FIFO)算法是将最早进入Cache的信息块替换出去。FIFO算法按调入Cache的前后决定淘汰的顺序,选择最早调入Cache的字块进行替换,它不需要记录各字块的使用情况,比较容易实现,系统开消小,其缺点是可能会把1些需要常常使用的程序可(如循环程序)也作为最早进入Cache的块替换掉,而且没有根据访存的局部性原理,故不能提高Cache的命中率。由于最早调入的信息可能以后还要用到,或常常要用到,如循环程序。此法简单、方便,利用了主存的“历史信息”,但其实不能说最早进入的就不常常使用,其缺点是不能正确反应程序局部性原理,命中率不高,可能出现1种异常现象。
(3)近期最少使用(LRU)算法。近期最少使用(Least Recently Used,LRU)算法是将近期最少使用的Cache中的信息块替换出去。该算法较先进先出算法要好1些,但此法也不能保证过去不经常使用将来也不经常使用。
LRU算法是根据各块使用的情况,总是选择那个最近最少使用的块被替换。这类方法虽然比较好地反应了程序局部性规律,但是这类替换方法需要随时记录Cache中各块的使用情况,以便肯定哪一个块是近期最少使用的块。LRU算法相对公道,但实现起来比较复杂,系统开消较大。通常需要对每块设置1个称为计数器的硬件或软件模块,用以记录其被使用的情况。
实现LRU策略的方法有很多种。简单介绍计数器法、寄存器栈法及硬件逻辑比较对法的设计思路。
计数器法:缓存的每块都设置1个计数器。计数器的操作规则以下:
(4)最优替换算法(OPT算法)。使用最优替换算法(OPTimal replacement Algorithm)时必须先履行1次程序,统计Cache的替换情况。有了这样的先验信息,在第2次履行该程序时即可以用最有效的方式来替换,以到达最优的目的。
前面介绍的几种页面替换算法主要是以主存储器中页面调度情况的历史信息为根据的,它假定将来主存储器中的页面调度情况与过去1段时间内主存储器中的页面调度情况是相同的,明显,这类假定不总是正确的。最好的算法应当是选择将来最久不被访问的页面作为被替换的页面,这类替换算法的命中率1定是最高的,它就是最优替换算法。
要实现OPT算法,唯1的办法是让程序先履行1遍,记录下实际的页地址流情况。根据这个页地址流才能找出当前要被替换的页面。明显,这样做是不现实的。因此,OPT算法只是1种理想化的算法,但是它也是1种很有用的算法。实际上,常常把这类算法用来作为评价其他页面替换算法好坏的标准。在其他条件相同的情况下,哪种页面替换算法的命中率与OPT算法最接近,那末它就是1种比较好的页面替换算法。
(5)最少使用算法(LFU算法 Least Frequently Used Algorithm)。选择最少访问的页面作为被替换的页面。明显,这是1种公道的算法,由于到目前为止最少使用的页面,极可能是将来最少访问的页面。该算法既充分利用了主存中页面调度情况的历史信息,又正确反应了程序的局部性。但是,这类算法实现起来非常困难,它要为每一个页面设置1个很长的计数器,并且要选择1个固定的时钟为每一个计数器定时计数。在选择被替换页面时,要从所有计数器中找出1个计数器值最大的计数器。
上一篇 农村电商:虽初见成效,但任重道远