分页系统中的设计问题

1.       局部分配策略与全局分配策略

局部页面置换算法:为每个进程分配固定的内存片段,每个进程页框数固定。

全局页面置换算法:在可运行进程之间动态分配页框,分配给每个进程的页框数是随时间变化的。

一般情况下,全局页面置换算法比较好,当工作集的大小随进程运行时间变化明显时更加明显。如此时使用局部页面置换算法,即使有大量空闲页面在,也可能会颠簸,工作集变小时,每个进程都会有大量的页框被闲置,造成内存浪费。使用全局算法时,系统必须随时确定应该给进程分配的页面多少,一种实现是用LRU的老化位监测工作集大小,然后这并没有什么卵用,因为,老化算法是根据时间滴答来确定页面集大小,间隔太长,工作集的大小往往几十微秒就波动很大了。

法1,定期确定进程数目,为其分配等额的页面,然而并不公平,有的进程需要多,有的需要少。

法2,根据进程的大小按比例为其分配页面。动态更新比例。管理动态内存的一种方法就是PPF,即缺页中断率算法,计算每秒的缺页中段数,当某个进程的缺页中断率高时,为他分配,低时剥夺页面。使得每个进程都保持在可接受范围内。

既适用于全局也适用于局部的算法有:LRU,FIFO

只适用于局部的是时钟集算法和工作集算法。

2.       负载控制

与分配算法无关,只要所有进程需要的页框数总和超过了内存容量,就可能发生颠簸。

原因是此时一些进程需要更多页面,但是没有更少的进程需要更少的内存,唯一的办法就是挂起某些进程,使用交换技术把内存交换到磁盘上去,以便让其它进程减小压力。

交换时要考虑进程是I/O密集型的还是CPU密集型的,以免CPU空闲。

3.       页面大小

页面大小的考虑以下元素:1.内部碎片,正文段、数据段可能填不满一个页面。剩余的就被浪费了。

2.更小的页面需要更大的页表,而内存与磁盘的传输是一次一页。传输速度会变慢,另外,某些机器上每次CPU从一个机器切换到另一个进程时需要把新进程的页表装入硬件寄存器,速度变慢。

  分离的指令空间和数据空间

大多数计算机只有一个地址空间,既存放程序也存放数据,当地址空间太小时,会很困难了。于是PDP-11就提出一种方案:为程序正文和数据设置两个空间,I空间和D空间链接器必须知道何时使用I空间和D空间,使用他们时,数据会被重定位到虚拟地址0,而不是程序之后开始。

 共享页面

   多道程序设计系统中,一个程序经常被多个用户运行,此时共享页面就很有用了,

如果机器支持I空间和D空间,就很简单,各个共享程序文段的进程使用相同的I空间不同的D空间页表就可以实现共享。每个进程在它的进程表中都有看个指针,一个指向I空间,一个指向D空间页表,使用这些指针来定位合适的页表。并使用他们来设立MMU。

假设进程A和进程B共享代码时,进程A结束时,调度程序决定从内存移走A的所有页面,于是要撤销,然而B就会出现大量缺页中断。因而需要专门的数据结构记住共享页面。

   共享数据比共享程序麻烦些,在UNIX中,在进行fork系统调用时,父进程与子进程要共享程序文本和数据,在分页系统中,通常是让这些进程分别拥有自己的页表,但是都指向一个页面集合,这样fork时就不必复制页面,此时两个进程中所有页面都是只读的,此后只要一点数据被改变了,就会触发只读保护,引发陷阱。随后生成该页的副本。这样每个进程都有自己的专用副本。这叫写时复制。可减少复制

      共享库                                 

1.静态绑定库,现代操作系统,很多大型库被众多进程使用。将所有库静态的与磁盘上的每一个可执行程序绑定在一起,会使他们更庞大。

2.共享库(windows称为DLL或动态链接库)

现在考虑传统链接库的方法

Linux中是这样的指令:ld * .o –lc–lm 这个命令的过程是这样的,链接当前目录下所有的.o文件,并扫描两个库:/usr/lib/libc.a和/usr/lib/libm.a。任何在目标文件中调用了但是没有被定义的函数(比如printf),都被称作未定义外部函数。链接器会在库中寻找这些未定义外部函数,若找到,把它们加载到可执行二进制文件中,任何被这些未定义外部函数调用了但是不存在的函数也会成为未定义外部函数,如printf中需要write,如果write没被加载进来,链接器就会查找write并把它加载进来,当链接器完成任务时,一个可执行二进制文件被写到磁盘,此时这个文件已经包含了所需的全部函数。在库中但是没有被定义的不会包含。当程序装入内存中使用时,所有函数已经就绪了

假设普通程序需要消耗20~50M用于图形和用户界面函数,静态链接上百个包括这些库的程序会浪费大量的磁盘空间,装载这些程序时也会浪费大量的内存空间。因为系统不知道它可以共享这些库,这就是引入共享库的原因。系统只会呆板的一遍一遍执行链接操作。

当一个程序与共享库有链接时,链接器不加载被调用的函数,而是加载了一小段能在运行时绑定的被调用函数的存根例程(stub routine)。依赖于系统和配置信息,共享库或者和程序一起被装载,或者在其所包含函数第一次被调用时被装载,如果其他程序已经装载了某个共享库,这个共享库就不会再次被装载,这样就避免了多次装载。当一个共享库被装载并使用时,整个库并不是被一次性的读入内存,而是根据需要,以页面为单位装载。因此没有调用到的函数是不会被装载到内存中的。

共享库优点:1.使可执行文件更小,节省内存空间。2.如果共享库中的一个函数有bug,那么不需要编译整个程序,只要更新DLL文件就可以!

共享库带来的小问题,若两个进程共享一个库,那么共享库可能会被定位到不同的地址上,而由于库共享,无法使用重定位。解决方法:编译共享库时,告诉编译器,不要产生使用绝对地址的指令,不论共享库放置在虚拟位置地址空间的什么位置,都可以正常工作。即位置无关代码。

3.内存映射文件

共享库是一种内存映射文件的特例。其核心思想是:进程可以通过发起一个系统调用,将一个文件映射到其虚拟地址空间的一部分,在大多数实现中,在映射共享的页面不会实际读入页面的内容,而是在访问页面时才会每次一页的读入,磁盘文件则被当做后备存储。当进程退出或显式的解除文件映射时,所有被改动的页面都会写回到文件。

内存映射文件提供了一种I/O的可选模型,可以把一个文件当做一个内存中的大字符数组来访问,而不用通过读写操作来访问这个文件。

如果两个或两个以上的进程同时映射了同一个文件,他们就可以通过共享内存来通信,一个进程在共享内存上完成了写操作,此刻当另一个进程在映射到这个文间的虚拟地址空间上执行读操作时,他就立即可以看到上一个进程写操作的结果,其实这就相当与一个进程之间的高带宽通道。

4.      清除策略

如果发生缺页中断系统中有大量的空闲页框,此时分页系统工作在最佳状态,如果每个页框都被占用,而且修改过话,再换入一个新页面时,旧页面应首先写回磁盘,为保证有足够的空闲页框,分页系统会有后台进程:后台守护进程,他大多数时候睡眠,定期被唤醒以检查内存的状态,如果空闲页框过少,分页守护进程通过预先的页面置换算法选择页面换出内存。如果这些页面被修改过,则写回磁盘

任何情况下,页面中原先的内容都被记录下来,但需要使用一个已被淘汰的页面时,如果该页框没有被覆盖,就把他从空闲页面缓冲池移出,保存一定数量的页框供给比效能比使用所有内存并在需要的时候搜索一个页框有更好的性能,分页守护进程至少保证所有的空闲页框都是干净的,在分配时不必急着写回磁盘。

实现清除策略的一种方法是:使用一个双指针时钟,当前指针由分页守护进程控制,当它指向一个脏页面时,就把页面写回磁盘,前指针移动,后指针用于页面置换,就像在标准时钟算法一样。这样后指针命中干净页面的概率会增大。

5.      虚拟内存接口

对于高级系统,允许程序员对内存映射进行控制

这样做的原因之一就是为了使多个进程共享同一部分内存。如果我们可以对内存区域命名,让一个进程把这片区域告诉另一个进程,第二个进程就可以把这片区域映射到自己的虚拟空间,从而实现高带宽的共享。

页面共享在消息传递的功能:进程控制他们的页面映射。发送进程清除对包含消息的信息映射,接受进程映射进来,这样避免了复制全部信息,只要复制页面的名字

时间: 2024-10-08 11:13:21

分页系统中的设计问题的相关文章

IM系统中聊天记录模块的设计与实现

看到很多开发IM系统的朋友都想实现聊天记录存储和查询这一不可或缺的功能,这里我就把自己前段时间为傲瑞通(OrayTalk)开发聊天记录模块的经验分享出来,供需要的朋友参考下. 一.总体设计 1.存储位置 从一开始我们就打算在服务端和客户端本地同时存储聊天记录,而且,在客户端查看聊天记录时,可以选择是从本地加载.还是从服务器加载.这样做的好处有两个: (1)从本地加载聊天记录速度非常快. (2)当更换了登录的机器,在任何地方任何时刻都可以从服务器加载完整的聊天记录,记录永远不会丢失. 2.存储方案

高效跑批设计思路——针对系统中的批量、日终任务

1. 跑批是什么 顾名思义,就是应用程序对数据的批量处理. 跑批有以下特性: 大数据量:批量任务一般伴随着大量的数据处理: 自动化:要求制定时间或频率自动运行: 性能:要求在指定时间内完成批处理任务. 2. 跑批应用场景 在开发中常见的跑批应用场景如下(以目前做的系统举例): 定时的数据状态更新:到期失效 数据的计算:计算罚息.计提 文件处理:与其他应用系统同步,如还款计划同步 生成文件:对账.提供同步文件 在跑批开发中有一些存有潜在隐患的处理方式需要指出来: 对文件内或数据库数据一次性读取.查

c语言中如何设计和编写一个应用系统?

C程序中,如何设计和编写一个应用系统? 一. C语言文件的操作 1. 文件操作的基本方法: C语言将计算机的输入输出设备都看作是文件.例如,键盘文件.屏幕文件等. 向屏幕输出一个信息,例如"Hello"是 #include.h> int main() { printf("Hello\\n"); } 从键盘接收一个字符串然后显示是 #include.h> int main() { char a[10]; scanf("%s",&

电商系统中的商品模型的分析与设计—续

前言     在<电商系统中的商品模型的分析与设计>中,对电商系统商品模型有一个粗浅的描述,后来有博友对货品和商品的区别以及属性有一些疑问.我也对此做一些研究,再次简单的对商品模型做一个介绍. 从SPU.SKU开始     首先我们需要澄清上篇中的这两个概念,在上篇文章中"货品"是指一种概念物品,这种物品并不是一个具体的实物,当它具备具体的属性.价格时,才是一种实物,也就是商品."商品"就是库存中一个具体的实物.例如:iphone6,就是一种货品,但用户

实现业务系统中的用户权限管理--设计篇

B/S系统中的权限比C/S中的更显的重要,C/S系统由于具有特殊的client,所以訪问用户的权限检測能够通过client实现或通过client+server检測实现,而B/S中,浏览器是每一台计算机都已具备的,假设不建立一个完整的权限检測,那么一个"非法用户"非常可能就能通过浏览器轻易訪问到B/S系统中的全部功能.因此B/S业务系统都须要有一个或多个权限系统来实现訪问权限检測,让经过授权的用户能够正常合法的使用已授权功能,而对那些未经授权的"非法用户"将会将他们彻

(3)MEF插件系统中通信机制的设计和实现

1.背景 一般的WinForm中通过C#自带的Event机制便能很好的实现事件的注册和分发,但是,在插件系统中却不能这么简单的直接用已有的类来完成.一个插件本不包含另外一个插件,它们均是独立解耦的,实现插件和插件间的通信还需要我们设计出一个事件引擎来完成这个需求. 目前很多高级语言中基本都实现了观察者模式,并进行了自己的包装.比如C#中的delegate和event组合,java awt中的Event和addActionListener组合,Flex中的Event.addEventListene

Python在信号与系统中的应用(1)——Hilbert变换,Hilbert在单边带包络检波的应用,FIR_LPF滤波器设计,还有逼格高高的FM(PM)调制

多谢董老师,董老师是个好老师! 心情久久不能平静,主要是高频这门课的分析方法实在是让我难以理解,公式也背不过,还是放放吧. 最近厌恶了Matlab臃肿的体积和频繁的读写对我的Mac的损害,所以学习了一下Python这一轻量级的脚本,发现"Python自诞生那天就跟科学计算分不开"这个事实.无聊,写写心得. 配置环境什么的还是弄了几个晚上的.在Mac下用PyCharm还是很好滴,装上NumPy,SciPy等等一众免费的,很不错的Python包,就可以灰了! 1.Hilbert变换及其在单

中小型商城系统中的分类/产品属性/扩展属性的数据库设计

声明:之所以定位在"中小型"商城系统,而非“大型”(指淘宝.拍拍这类巨无霸),理由很简单----我一直都呆在(创业型的)小公司,没见过这些大家伙是怎么设计的:) 正文: 之前发表过一篇"商城系统中[商品扩展属性]的表单生成及客户端验证",部分童鞋对于后台数据库的设计比较感兴趣,于是今天把这部分也补上. 一.产品分类设计越来越多的商城系统都热衷于选择“无限级分类”的设计,我也不例外,因为它方便扩展.这部分就不详细展开了,详见 无限级分类(非递归算法/存储过程版/GUI

电商系统中的商品模型的分析与设计

前言 在电商系统中,商品模型至关重要,是整个电商的核心,下面通过一个简单的分析,设计一个基础的商品模型. 商品模型的演化 在以前,那时CMS很流行,最常见的模型是栏目-文章模型.于是做电商的时候,自然就继承了这种一对多的关系.只是栏目变成了分类,文章变成了商品.商品也具备了独特的业务属性.现在很多电商网站上左侧的菜单,也就是这个分类. 后来我们慢慢发现一个问题,只有分类并不能适应所有的需求,比如nike鞋和nikeT恤,用户可能希望先看nike的所有商品,这个模型就不能满足.我们想在这个关系中,