3.5 分页系统中的设计问题
1. 局部分配策略与全局分配策略
怎样在相互竞争的可运行进程之间分配内存?
淘汰内存中页面是不管它属于哪个进程(全局页面置换算法)还是只选属于该进程的(局部页面置换算法)。
一般情况下,全局算法比局部算法好,当工作集大小随进程运行时间发生变化时更明显。
若使用局部算法:有大量空闲页框存在,工作集的增长也会导致颠簸;而如果工作集缩小又会浪费内存。
使用全局算法时需要不停地确定该给每个进程分配多少页框。
- 检测工作集大小
- 定期确定进程运行数目并分配相同份额 (不太合理)
- 可以按照进程大小的比例来
工作集算法是针对某些特定进程的而且必须应用在这些进程的上下文中,实际上没有针对整个机器的工作集,所以工作集算法并不能用作全局算法。、
2. 负载控制
一个进程可以被交换到磁盘,它的页框从而可以被其他处于颠簸状态的进程分享;如果颠簸停止则系统这样运行,如果还是颠簸就继续把其他进程交换出去直至颠簸结束。
一些进程被周期性地从磁盘调入,而其他一些则被周期性的交换到磁盘。
3. 页面大小
小页面优点:
- 减少内部碎片浪费(正文段、数据段、堆栈段都很可能不会恰好装满整个页面,平均情况下,最后一个页面有一半是空的)
- 大页面使更多没用的程序保留在内存中(一个只需要4K的,如果页面大小32K,就浪费了)
缺点:
- 更大的页表(传输一个小页面的页表和大页面的页表时间基本相同),而CPU从一个进程切到另一个时都必须把新进程的页表装入硬件寄存器,这样会花费更多的时间。
4. 分离的指令空间和数据空间
为指令(程序正文)和数据设置分离的地址空间,分别为I空间和D空间。每个地址空间都从0增大,都可以进行分页而且相互独立,拥有自己的页表。
5. 共享页面
避免内存中有一个页面的两份副本,共享页面效率更高。但只有只读的页面(如程序文本)可以共享,数据页面不能共享!!!!
如果系统支持分离的I空间和D空间,那么共享程序就非常简单了。
进程表有两个指针分别指向I空间和D空间的页表
![](https://i-blog.csdnimg.cn/blog_migrate/649c5545cc1d354bac2917ba6879f893.png)
可能出现问题:AB共享,但当A结束时共享页面也被收走了。
因此需要记录共享页面!
只要两个进程都只是读数据就可以一直保持下去,但只要有一个进程更新了数据,就会触发只读保护,引发操作系统陷阱,生成一个副本,这样每个进程都有自己的可以读写的专用副本,随后对任何一个副本的写操作都不会再引发陷阱。========》写时保护。
6. 共享库
很多大型库被众多进程使用,如果静态地和每一个可执行程序绑定在一起,会变得很庞大。
静态库优点:
- 代码装载速度快,执行速度略比动态链接库快;
- 只需保证在开发者的计算机中有正确的.LIB文件,在以二进制形式发布程序时不需考虑在用户的计算机上.LIB文件是否存在及版本问题,可避免DLL地狱等问题。
共享库(WINDOWS称DLL或动态链接库)
共享库不同于静态库,链接器没有加载被调用的函数,而是加载一小段能够在运行时绑定被调用函数的存根例程。依赖于系统和配置信息,共享库或者和程序一起被装载,或者在其包含函数第一次被调用时被装载。如果其他程序已经装载了整个共享库,那么就没有必要再次装载。
当一个共享库被装载和使用时,不是一次性读入内存,而是以页面为单位,根据需要,被调用到的才被装载到内存中。
优点:
- 更加节省内存并减少页面交换;
- DLL文件与EXE文件独立,只要输出接口不变(即名称、参数、返回值类型和调用约定不变),更换DLL文件不会对EXE文件造成任何影响,因而极大地提高了可维护性和可扩展性;
- 不同编程语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数;
- 适用于大规模的软件开发,使开发过程独立、耦合度小,便于不同开发者和开发组织之间进行开发和测试。
缺点:
- 使用动态链接库的应用程序不是自完备的,它依赖的DLL模块也要存在,如果使用载入时动态链接,程序启动时发现DLL不存在,系统将终止程序并给出错误信息。而使用运行时动态链接,系统不会终止,但由于DLL中的导出函数不可用,程序会加载失败;速度比静态链接慢。当某个模块更新后,如果新模块与旧的模块不兼容,那么那些需要该模块才能运行的软件,统统撕掉。这在早期Windows中很常见。
- 装载时地址重定位行不通(有一个解决方法:编译共享库时,用一个特殊的编译选项高速编译器不要产生使用绝对地址的指令,而只使用相对地址,这种代码叫 位置无关代码)
3.7 内存映射文件
共享库是内存映射文件的一个特例。
如果两个及以上进程同时映射了同一个文件,他们就可以通过共享内存来通信。一个进程在共享内存上完成写操作,另一个读。
3.8 清除策略
很多分页系统有个分页守护进程,大多数情况下睡眠,但定期被唤醒以检查内存状态,如果内存页框太少就置换页面。
有一种实现清楚策略的方法:双指针时钟。
前指针由分页守护进程控制,指向一个脏页面时就把它写回磁盘并前移;如果指向干净页面就只前移。
后指针用于页面置换,就像标准的时钟算法一样。
2018/03/15 13:07