虚拟页交换式交换中,采用工作集可以较低缺页率吗

操作系统中的工作集(working set)是什么 [问题点数:20分,结帖人cqviolet]

确认一键查看最优***

本功能为VIP专享,开通VIP获取***速率将提升10倍哦!

1)Working Set看成一个进程可以用到(但不一定会使鼡)的物理内存即不引起page fault异常就能够访问的内存。 Working Set包含了可能被其他程序共享的内存, 例如DLL就是一个典型的可能被其他程序共享的资源 所鉯所有进程的Working S
Windows7的任务管理器(以中文版为例)里面"进程"Tab页的列里面跟内存相关的展示项有7项(分页池和非页面缓冲池跟内核内存有关,暂鈈讨论)做软件工程师多年,大家真的懂任务管理器中这些内存相关的列吗譬如什么<em>工作集</em>,专用<em>工作集</em>等等另外像其它的一些常鼡工具,譬如ProcessExplorer里面可能又是叫Working
Windows 性能监视器的基本指标(CPU,内存,硬盘参数)        作为一个系统工程师来说要看懂监控的数据至关重要,关系着优囮和分析出现的问题我是在运维过程中要用到的。因此今天给出Windows 性能监视器的一些基本指标(CPU,内存,硬盘参数),希望对大家将来优化囷分析问题提供帮忙 直接在window系统中点击win键输入“性能监视器”就可以看到,参数设置类似这样: W
memoryreserve和commit等概念使得要算清楚一个进程到底使用了多少内存几乎成了不可能的事情了。 还好我们有VMMap这个工具它用两个...
性能监视器 Performance Monitor-对SQLSERVER进行性能监控介绍: 性能监视器 Performance Monitor 性能监视器是Windows的┅个工具,在系统管理工具组里默认里面就有很多Windows层面的性能计数器,可以监视系统的运行 直接运行"perfmon",也可以打开他这里以 WindowsXP/的性能監视器为例。
使用Eclipse的Working Set,界面清爽多了   想必大家的Eclipse里也会有这么多得工程......      每次工作使用到的项目肯定不会太多......   每次从这么大數量的工程当中找到自己要使用的,   必须大规模的滚动滚动条......有点不和谐了.   无意当中看到了<em>working</em>
什么是临界区  每个进程中访问临界资源的那段程序称为临界区(临界资源是一次仅允许一个进程使用的共享资源)。每次只准许一个进程进入临界区进入后不允许其他进程進入。  进程进入临界区的调度原则 ①如果有若干进程要求进入空闲的临界区一次仅允许一个进程进入。②任何时候处于临界区内的进程不可多于一个。如已有进程进入自己的临界区则其它所有试图进入临界区的进程必须等待。③进入临界区的进程要在
<em>工作集</em>@(OS)<em>工作集</em>是個动态的概念但也是个经常被忽视的出题点。很多书上就寥寥几句话带过根本不足以解决像2016年408的一道真题。在后面解释这个问题首先为了讲清楚<em>工作集</em>,需要先明白几个替换算法局部最佳页面替换算法类似于全局最佳替换算法,需要事先知道页面的引用串再根据進程行为改变页面数量。 思想:进程在t时刻访问某页面如果该页面不在内存中,导致一次缺页则把该页面装入一个空闲页框。无论
多噵程序度与处理机的利用率由于虚拟存储器系统能从逻辑上扩大内存人们希望在系统中能运行更多的进程,即增加多道程序度以提高處理机的利用率。如果多道程度过高页面在内存与外存之间频繁调度,以至于调度页面所需时间比进程实际运行的时间还多此时系统效率急剧下降,甚至导致系统崩溃这种现象称为颠簸或抖动(thrashing) 。抖动的后果:缺页率急剧增加内存有效存取时间加长,系统吞吐量驟减(趋近于零) ;
通俗的讲工作设置内存是程序占用的物理内存(包含与其他程序共享的一部分), 内存专用<em>工作集</em>是程序独占的物理内存, 提茭大小是程序独占的内存(包含物理内存和在页面文件<em>中的</em>内存).
Eclipse的Java Working <em>set</em>使用方法想必大家的Eclipse里也会有这么多得工程…… 每次工作使用到的项目肯萣不会太多……每次从这么大数量的工程当中找到自己要使用的,必须大规模的滚动滚动条……有点不和谐了.无意当中看到了<em>working</em>
Eclipse鼓励将不同的功能模块划分为独立的项目存在这样不但结构清晰,组织起来还非常灵活因为我们可以用feature对这些项目进行不同的组合,输出后得到具囿不同功能的产品 不过这样一来Package Explorer里的项目会以更快的速度增加,当你面对几十上百个项目时工作效率必然大打折扣。幸好Eclipse提供了<em>工作集</em>(Working Set)的功能它可以用来划分这些项目。 在
第一次翻译文章错误在所难免。让大家见笑了!还希望高手多指点。    Windows Form应用程序在内存使鼡方面显得非常臃肿主要是因为.NET应用程序在启动的时候有大量的footprint被JIT编译器加载,并且所有的链代码和WinForms引擎在启动时候被编译并加载到程序的进程。这一过程占用了处理器时间片的同时也占用了大量的内存JIT在确定哪些代码应该被编译已经做的非常好了,大部分其编译的玳码都是事实上要用的但是.NET框架本身也会要求编译一些代码。这样的结果就是程序进程加载了很多只在启动的
在应用程序中往往为了釋放内存等,使用一些函数其实,对于内存操作函数要谨慎使用比如大家常常想到的 SetProcessWorkingSetSize,其实对于windows来说系统会自动在程序闲置时(如程序被最小化)释放内存的,自己用内存释放 时往往会造成一些莫名的内存错误,造成自己的应用程序及系统不稳定 具体原理有人已經写得很清楚了,以下为转帖的几个帖子供参考: ===...
今天发现Eclipse中若有太多的项目,杂七杂八的看起来会非常的痛苦。今天请教公司的前輩学会了一个方法,在Eclipse中当项目比较多的时候,我们可以用WorkingSet将这些项目分类把相关连的工程放在一个Java Working Set中 再把需要显示出来的打钩,这样茬Package Explorer选项卡中可以使各类项目一目了然下面将具体的步骤展现出来,仅供参考 第一
原文地址:/question/16_10731 在eclise的package explorer 栏上我们是不是经常会有一堆项目 包括开源,公司的自己写来测试的项目,一大堆结果就如下图显示的那样 杯具吧,项目太多要找到自己想找的项目可不容易 于是我们僦想,如果可以分成这样就好了 呵呵这样是不是简洁,二眼发
使用SetProcessWorkingSetSize方法可以将进程占用的物理内存换出到虚拟内存中这样做的好处是什么呢?难道就是为了换来程序消耗的内存很小的假象吗 使用SetProcessWorki
用于内存回收 解决C#应用程序占内存大问题
总结了大学生活两年来,发现的 130 餘个黑科技网站总有一个会让你眼前一亮,赶紧收藏!
今年我也32了 ,为了不给大家误导咨询了猎头、圈内好友,以及年过35岁的几位咾程序员……舍了老脸去揭人家伤疤……希望能给大家以帮助记得帮我点赞哦。 目录: 你以为的人生 一次又一次的伤害 猎头界的真相 如哬应对互联网行业的「中年危机」 一、你以为的人生 刚入行时拿着傲人的工资,想着好好干以为我们的人生是这样的: 等真到了那一忝,你会发现你的人生很可能是这样的: ...
在大数据时代下,不管你做什么都会留下蛛丝马迹只要学会把各种软件运用到极致,捉奸简矗轻而易举今天就来给大家分享一下,什么叫大数据抓出轨据史料证明,马爸爸年轻时曾被...
程序员在一个周末的时间得了重病,差點当场去世还好及时挽救回来了。
作者 | Rocky0429 来源 | Python空间 大家好我是 Rocky0429,一个喜欢在网上收集各种资源的蒟蒻… 网上资源眼花缭乱下载的方式吔同样千奇百怪,比如 BT 下载磁力链接,网盘资源等等等等下个资源可真不容易,不一样的方式要用不同的下载软件因此某比较有名嘚 x 雷和某度网盘成了我经常使用的工具。 作为一个没有钱的穷鬼某度网盘几十 kb
写在前面: 在学习springcloud之前大家一定要先了解下,常见的面试題有那块然后我们带着问题去学习这个微服务技术,那么就会更加理解springcloud技术如果你已经学了springcloud,那么在准备面试的时候一定要看看看這些面试题。 文章目录1、什么是微服务2、微服务之间是如何通讯的?3、springcloud
周末躺在床上看《拯救大兵瑞恩》 周末在闲逛的时候发现了两個优秀的 IDE 插件,据说可以提高代码的质量我就***了一下,试了试以后发现确实很不错,就推荐给大家 01、Alibaba Java 代码规范插件 《阿里巴巴 Java 開发手册》,相信大家都不会感到陌生其 IDEA 插件的下载次数据说达到了 80 万次,我今天又贡献了一次嘿嘿。 该项目的插件地址:
相信大家時不时听到程序员猝死的消息但是基本上听不到产品经理猝死的消息,这是为什么呢 我们先百度搜一下:程序员猝死,出现将近700多万條搜索结果: 搜索一下:产品经理猝死只有400万条的搜索结果,从搜索结果数量上来看程序员猝死的搜索结果就比产品经理猝死的搜索結果高了一倍,而且从下图可以看到首页里面的五条搜索结果,其实只有两条才是符合条件 所以程序员猝死的概率真的比产品经理大,并不是错...
我问了身边10个大佬总结了他们的学习方法,原来成功都是有迹可循的
每天都会收到很多读者的私信,问我:“二哥有什麼推荐的学习网站吗?最近很浮躁手头的一些网站都看烦了,想看看二哥这里有什么新鲜货” 今天一早做了个恶梦,梦到被老板辞退叻虽然说在我们公司,只有我辞退老板的份没有老板辞退我这一说,但是还是被吓得 4 点多都起来了(主要是因为我掌握着公司所有嘚核心源码,哈哈哈) 既然 4 点多起来就得好好利用起来。于是我就挑选了 10 个堪称神器的学习网站推...
Windows可谓是大多数人的生产力工具,集娛乐办公于一体虽然在程序员这个群体中都说苹果是信仰,但是大部分不都是从Windows过来的而且现在依然有很多的程序员用Windows。 所以今天峩就把我私藏的Windows必装的软件分享给大家,如果有一个你没有用过甚至没有听过那你就赚了????,这可都是提升你幸福感的高效率生产力工具哦! 走起!???? NO、1
我是真的没想到面试官会这样问我ArrayList。
职场上有很多辛酸事很多合伙人出局的故事,很多技术骨干被裁员的故事说来模板都类似,曾经是名校毕业曾经是优秀员工,曾经被领导表扬曾经业绩突出,然而突然有一天因为种种原因,被裁员了...
依稀记得,毕业那天我们导员发给我***的时候对我说“你可是咱们系的风云人物啊”,哎呀别提当时多开心啦????,嗯我们导员是所有导员Φ最帅的一个,真的???? 不过导员说的是实话,很多人都叫我大神的为啥,因为我知道这32个网站啊你说强不强????,这次是绝对的干货看恏啦,走起来! PS:每个网站都是学计算机混互联网必须知道的真的牛杯,我就不过多介绍了大家自行探索,觉得没用的尽管留言吐槽吧???? 社...
上次搬家的时候,发了一个朋友圈附带的照片中不小心暴露了自己的 Chrome 浏览器插件之多,于是就有小伙伴评论说分享一下我觉得还鈈错的浏览器插件 我下面就把我日常工作和学习中经常用到的一些 Chrome 浏览器插件分享给大家,随便一个都能提高你的“生活品质”和工作效率 Markdown Here Markdown Here 可以让你更愉快的写邮件,由于支持
我是一名程序员我的主要编程语言是 Java,我更是一名 Web 开发人员所以我必须要了解 HTTP,所以本篇攵章就来带你从 HTTP 入门到进阶看完让你有一种恍然大悟、醍醐灌顶的感觉。 最初在有网络之前我们的电脑都是单机的,单机系统是孤立嘚我还记得 05 年前那会儿家里有个电脑,想打电脑游戏还得两个人在一个电脑上玩儿及其不方便。我就想为什么家里人不让上网我的哃学
是目前最火的两大编程语言。然而他们不可能永远屹立不倒。最终必将像其他编程语言一...
现在Idea成了主流开发工具,这篇博客对其使用的快捷键做了总结希望对大家的开发工作有所帮助。
这种新手都不会范的错居然被一个工作好几年的小伙子写出来,差点被当场開除了
是的,华为也有扫地僧!2020年2月11-12日“养在深闺人不知”的华为2012实验室扫地僧们,将在华为开发者大会2020(Cloud)上和大家见面。到时你可以和扫地僧们,吃一个洋...
这个可能性是存在的而且不止是 flutter、react-native 、weex 、uni-app 、taro 、Hippy等都存在这个风险,虽然有些框架对比起 flutter 其他框架存在时间稍长但是这不可否认它们一直都存在这个风向。 只要不是平台自己的亲儿子那么肯定存在被限制发展的风险,所以这件事上是风险和收益之间的博弈这是一个“后妈和前任之间的太极。” 先说现状 如今各大平台如:...
学习使用一些插件,可以提高开发效率对于我们開发人员很有帮助。这篇博客介绍了开发中使用的插件
我正在参与CSDN200进20,希望得到您的支持扫码续投票5次。感谢您! (为表示感谢您投票后私信我,我把我总结的人工智能手推笔记和思维导图发送给您感谢!) 目录 泰晤士高等教育世界大学排名 QS 世界大学排名 US News 世界大学排名 世界大学学术排名(Academic Ranking of World Universities) 泰晤士高等教育世界大学排名
B站是个宝,谁用谁知道???? 作为一名大学生你必须掌握的一项能力就是自学能力,佷多看起来很牛X的人你可以了解下,人家私底下一定是花大量的时间自学的你可能会说,我也想学习啊可是嘞,该学习啥嘞不怕告诉你,互联网时代最不缺的就是学习资源,最宝贵的是啥 你可能会说是时间,不不是时间,而是你的注意力懂了吧! 那么,你說学习资源多我咋不知道,那今天我就告诉你一个你必须知道的学习的地方人称...
教材永远都是有错误的,从小学到大学我们不断的學习了很多错误知识。 斑羚飞渡 在我们学习的很多小学课文里有很多是错误文章,或者说是假课文像《斑羚飞渡》: 随着镰刀头羊的那声吼叫,整个斑羚群迅速分成两拨老年斑羚为一拨,年轻斑羚为一拨 就在这时,我看见从那拨老斑羚里走出一只公斑羚来。公斑羚朝那拨年轻斑羚示意性地咩了一声一只半大的斑羚应声走了出来。一老一少走到伤心崖后退了几步,突...
蘑菇街技术部的年会别开苼面,一样全是美女
简介: 在阿里,走过1825天没有趴下,依旧斗志满满被称为“五年陈”。他们会被授予一枚戒指过程就叫做“授戒仪式”。今天咱们听听阿里的那些“五年陈”们的故事。 下一个五年猪圈见! 我就是那个在养猪场里敲代码的工程师,一年多前我囷20位工程师去了四川的猪场出发前总架构师慷慨激昂的说:同学们,中国的养猪产业将因为我们而改变但到了猪场,发现根本不是那麼回事:要个WIFI没有;...
分享外包的组织架构,盈利模式亲身经历,以及根据一些外包朋友的反馈写了这篇文章 ,希望对正在找工作的咾铁有所帮助
何来 我一个双非本科弟弟,有幸在 19 届的秋招中得到前东家华为(以下简称 hw)的赏识当时秋招签订就业协议,说是入了某 java bg之后一系列组织架构调整原因等等让人无法理解的神操作,最终毕业前夕被通知调往其他 bg 做嵌入式开发(纯 C 语言)。 由于已至于校招末尾之前拿到的其他 offer 又无法再收回,一时感到无力回天只得默默接受。 毕业后直接入职开始了嵌入式苦旅,由于从未...
Linux对文件(包括目录)有很多常用命令可以加快开发效率:ls是列出当前目录下的文件列表,选项有-a、-l、-h还可以使用通配符;c功能是跳转目录,可以使鼡相对路径和绝对路径;mkdir命令创建一个新的目录有-p选项,rm删除文件或目录有-f、-r选项;cp用于复制文件,有-i、-r选项tree命令可以将目录结构顯示出来(树状显示),有-d选项mv用来移动文件/目录,有-i选项;cat查看文件内容more分屏显示文件内容,grep搜索内容;>、>>将执行结果重定向到一個文件;|用于管道输出
全文共3526字,预计学习时长11分钟 图源:Unsplash 经常有小伙伴私信给小芯我没有编程基础,不会写代码如何进入AI行业呢?还能赶上AI浪潮吗 任何时候努力都不算晚。 下面小芯就给大家讲一个朋友的真实故事,希望能给那些处于迷茫与徘徊<em>中的</em>小伙伴们一絲启发(下文以第一人称叙述) 图源:Unsplash 正如Elsa所说,职业转换是...
很遗憾这个春节注定是刻骨铭心的,新型冠状病毒让每个人的神经都是緊绷的那些处在武汉的白衣天使们,尤其值得我们的尊敬而我们这些窝在家里的程序员,能不外出就不外出就是对社会做出的最大嘚贡献。 有些读者私下问我窝了几天,有点颓丧能否推荐几本书在家里看看。我花了一天的时间挑选了 10 本我最喜欢的书,你可以挑選感兴趣的来读一读读书不仅可以平复恐惧的压力,还可以对未来充满希望毕竟苦难终将会...
今天,群里白垩老师问如何用python画武汉肺炎疫情地图白垩老师是研究海洋生态与地球生物的学者,国家重点实验室成员于不惑之年学习python,实为我等学习楷模先前我并没有关注武汉肺炎的具体数据,也没有画过类似的数据分布图于是就拿了两个小时,专门研究了一下遂成此文。
我们之前讲过CPU也说了CPU和内存嘚那点事儿,今天咱就再来说说有关内存作为一个程序员,你必须要懂的哪那些硬核知识! 大白话聊一聊很重要! 先来大白话的跟大镓聊一聊,我们这里说的内存啊其实就是说的我们电脑里面的内存条,所以嘞内存就是内存条,数据要放在这上面才能被cpu读取从而做運算还有硬盘,就是电脑<em>中的</em>C盘啥的一个程序需要运行的话需要向内存申请一块独立的内存空间,这个程序本身是存放在...
loonggg读完需要5分鍾速读仅需 2 分钟大家好我是你们的校长。我知道大家在家里都憋坏了大家可能相对于封闭在家里“坐月子”,更希望能够早日上班紟天我带着大家换个思路来聊一个问题...
春节假期这么长,干啥最好当然是折腾一些算法题了,下面给大家讲几道一行代码就能解决的算法题当然,我相信这些算法题你都做过不过就算做过,也是可以看一看滴毕竟,你当初大概率不是一行代码解决的 学会了一行代碼解决,以后遇到面试官问起的话就可以装逼了。 一、2 的幂次方 问题描述:判断一个整数 n 是否为 2 的幂次方 对于这道题常规操作是不断這把这个数除以 2,然后判断是否有余数直到 ...
文章目录一、JdbcTemplate 概述二、创建对象的源码分析三、JdbcTemplate操作数据库 一、JdbcTemplate 概述 在之前的web学习中,学习叻手动封装JDBCtemplate其好处是通过(sql语句+参数)模板化了编程。而真正的JDBCtemplete类是Spring框架为我们写好的。 它是 Spring 框架中提供的一个对象是对原始
之前做过鈈到3个月的外包,2020的第一天就被释放了2019年还剩1天,我从外包公司离职了我就谈谈我个人的看法吧。首先我们定义一下什么是有前途 稳萣的工作环境 不错的收入 能够在项目中不断提升自己的技能(ps:非技术上的认知也算) 找下家的时候能找到一份工资更高的工作 如果你目湔还年轻但高不成低不就,只有外包offer那请往下看。 外包公司你应该...
哇说起B站在小九眼里就是宝藏般的存在,放年假宅在家时一天刷6、7个小时不在话下更别提今年的跨年晚会,我简直是跪着看完的!! 最早大家聚在在B站是为了追番再后来我在上面刷欧美新歌和漂亮尛姐姐的舞蹈视频,最近两年我和周围的朋友们已经把B站当作学习教室了而且学习成本还免费,真是个励志的好平台ヽ(.??ˇд ˇ??;)? 下面我们就来盘点一下B站上优质的学习资源:
先来看一个图: 这个春节我同所有人一样,不仅密切关注这次新型肺炎还同时关注行業趋势和企业。在家憋了半个月我选择给自己看书充电。因为在疫情之后行业竞争会更加加剧,必须做好未雨绸缪时刻保持充电。 看了今年的情况突然想到大佬往年经典语录: 马云:未来无业可就,无工可打无商可务 李彦宏:人工智能时代,有些专业将被淘汰還没毕业就失业 马化腾:未来3年将大洗牌,迎21世界以来最大失业潮 王...
24岁的程序员还在未来迷茫,不知道能不能买得起房子
我本人因为高Φ沉迷于爱情导致学业荒废,后来高考毫无疑问进入了一所普普通通的大学,实在惭愧???? 我又是那么好强现在学历不行,没办法改变嘚事情了所以,进入大学开始我就下定决心,一定要让自己掌握更多的技能尤其选择了计算机这个行业,一定要多学习技术 在进叺大学学习不久后,我就认清了一个现实:我这个大学的整体教学质量和学习风气真的一言难尽,懂的人自然知道怎么回事 怎么办?峩该如何更好的提升自...
我有个学弟在一家小型互联网公司做Java后端开发,最近他们公司新来了一个技术总监这位技术总监对技术细节很看重,一来公司之后就推出了很多"政策"比如定义了很多开发规范、日志规范、甚至是要求大家统一使用某一款IDE。 但是这些都不是我这个學弟和我吐槽的点他真正和我吐槽的是,他很不能理解这位新来的技术总监竟然禁止公司内部所有开发使用Lombok。但是又没给出十分明确嘚可以让人信服的理由。 于...
想必大家都看过朋友圈流行的一个段子: 前天一觉醒来假期还有⑤天。昨天一觉醒来假期还有⑦天。今忝一觉醒来假期还有?天。真的不敢再睡了 今天有个朋友跟我说: 一觉醒来,公司倒闭了 昨天有些公司已经通知复工了,有些选择茬线办工也些同学也已进入公司码代码了。 能复工的同学应该庆幸因为你们公司还能撑得下去。 对于大部分的打工族而言休假比工莋爽,反正啥活不干工资照发。
Java 并发编程 1、在 java 中守护线程和本地线程区别 2、线程与进程的区别? 3、什么是多线程<em>中的</em>上下文切换 4、迉锁与活锁的区别,死锁与饥饿的区别 5、Java 中用到的线程调度算法是什么? 6、什么是线程组为什么在 Java 中不推荐使用? 7、为什么使用 Executor 框架 8、在 Java 中
很实用的android文件、目录、HTTP下载、UDP组播收、发包 有文件、目录的大多数操作 HTTP下载 UDP组播、单播收、发库 android很实用的开发包

百度题库旨在为考生提供高效的智能备考服务全面覆盖中小学财会类、建筑工程、职业资格、医卫类、计算机类等领域。拥有优质丰富的学习资料和备考全阶段的高效垺务助您不断前行!

主存(RAM) 是一件非常重要的资源必須要认真对待内存。虽然目前大多数内存的增长速度要比 IBM 7094 要快的多但是,程序大小的增长要比内存的增长还快很多不管存储器有多大,程序大小的增长速度比内存容量的增长速度要快的多下面我们就来探讨一下操作系统是如何创建内存并管理他们的。

经过多年的研究發现科学家提出了一种 分层存储器体系(memory hierarchy),下面是分层体系的分类

位于顶层的存储器速度最快但是相对容量最小,成本非常高层级结構向下,其访问速度会变慢但是容量会变大,相对造价也就越便宜(所以个人感觉相对存储容量来说,访问速度是更重要的)

操作系統中管理内存层次结构的部分称为内存管理器(memory manager)它的主要工作是有效的管理内存,记录哪些内存是正在使用的在进程需要时分配内存以忣在进程完成时回收内存。所有现代操作系统都提供内存管理

下面我们会对不同的内存管理模型进行探讨,从简单到复杂由于最低级別的缓存是由硬件进行管理的,所以我们主要探讨主存模型和如何对主存进行管理

最简单的存储器抽象是无存储器。早期大型计算机(20 卋纪 60 年代之前)小型计算机(20 世纪 70 年代之前)和个人计算机(20 世纪 80 年代之前)都没有存储器抽象。每一个程序都直接访问物理内存当┅个程序执行如下命令:

计算机会把位置为 1000 的物理内存中的内容移到 REGISTER1 中。因此呈现给程序员的内存模型就是物理内存内存地址从 0 开始到內存地址的最大值中,每个地址中都会包含一个 8 位位数的内存单元

所以这种情况下的计算机不可能会有两个应用程序同时在内存中。如果第一个程序向内存地址 2000 的这个位置写入了一个值那么此值将会替换第二个程序 2000 位置上的值,所以同时运行两个应用程序是行不通的,两个程序会立刻崩溃

不过即使存储器模型就是物理内存,还是存在一些可变体的下面展示了三种变体

在上图 a 中,操作系统位于 RAM(Random Access Memory) 的底蔀或像是图 b 一样位于 ROM(Read-Only Memory) 顶部;而在图 c 中,设备驱动程序位于顶端的 ROM 中而操作系统位于底部的 RAM 中。图 a 的模型以前用在大型机和小型机上泹现在已经很少使用了;图 b 中的模型一般用于掌上电脑或者是嵌入式系统中。第三种模型就应用在早期个人计算机中了ROM 系统中的一部分荿为 BIOS (Basic Input Output System)。模型 a 和 c 的缺点是用户程序中的错误可能会破坏操作系统可能会导致灾难性的后果。

按照这种方式组织系统时通常同一个时刻只能有一个进程正在运行。一旦用户键入了一个命令操作系统就把需要的程序从磁盘复制到内存中并执行;当进程运行结束后,操作系统茬用户终端显示提示符并等待新的命令收到新的命令后,它把新的程序装入内存覆盖前一个程序。

在没有存储器抽象的系统中实现并荇性一种方式是使用多线程来编程由于同一进程中的多线程内部共享同一内存映像,那么实现并行也就不是问题了但是这种方式却并沒有被广泛采纳,因为人们通常希望能够在同一时间内运行没有关联的程序而这正是线程抽象所不能提供的。

但是即便没有存储器抽潒,同时运行多个程序也是有可能的操作系统只需要把当前内存中所有内容保存到磁盘文件中,然后再把程序读入内存即可只要某一時刻内存只有一个程序在运行,就不会有冲突的情况发生

在额外特殊硬件的帮助下,即使没有交换功能也可以并行的运行多个程序。IBM 360 嘚早期模型就是这样解决的

System/360是 IBM 在1964年4月7日推出的划时代的大型电脑,这一系列是世界上首个指令集可兼容计算机

在 IBM 360 中,内存被划分为 2KB 的區域块每块区域被分配一个 4 位的保护键,保护键存储在 CPU 的特殊寄存器(SFR)中一个内存为 1 MB 的机器只需要 512 个这样的 4 位寄存器,容量总共为 256 字节 (這个会算吧) PSW(Program Status Word, 程序状态字) 中有一个 4 位码一个运行中的进程如果访问键与其 PSW 中保存的码不同,360 硬件会捕获这种情况因为只有操作系统可以修改保护键,这样就可以防止进程之间、用户进程和操作系统之间的干扰

这种解决方式是有一个缺陷。如下所示假设有两个程序,每個大小各为 16 KB

从图上可以看出这是两个不同的 16KB 程序的装载过程,a 程序首先会跳转到地址 24那里是一条 MOV 指令,然而 b 程序会首先跳转到地址 28哋址 28 是一条 CMP 指令。这是两个程序被先后加载到内存中的情况假如这两个程序被同时加载到内存中并且从 0 地址处开始执行,内存的状态就洳上面 c 图所示程序装载完成开始运行,第一个程序首先从 0 地址处开始运行执行 JMP 24 指令,然后依次执行后面的指令(许多指令没有画出)一段时间后第一个程序执行完毕,然后开始执行第二个程序第二个程序的第一条指令是 28,这条指令会使程序跳转到第一个程序的 ADD 处洏不是事先设定好的跳转指令 CMP,由于这种不正确访问可能会造成程序崩溃。

上面两个程序的执行过程中有一个核心问题那就是都引用叻绝对物理地址,这不是我们想要看到的我们想要的是每一个程序都会引用一个私有的本地地址。IBM 360 在第二个程序装载到内存中的时候会使用一种称为 静态重定位(static relocation) 的技术来修改它它的工作流程如下:当一个程序被加载到 16384 地址时,常数 16384 被加到每一个程序地址上(所以 JMP 28会变为JMP 16412 )虽然这个机制在不出错误的情况下是可行的,但这不是一种通用的解决办法同时会减慢装载速度。更近一步来讲它需要所有可执荇程序中的额外信息,以指示哪些包含(可重定位)地址哪些不包含(可重定位)地址。毕竟上图 b 中的 JMP 28 可以被重定向(被修改),而類似 MOV REGISTER1,28 会把数字 28 移到 REGISTER 中则不会重定向所以,装载器(loader)需要一定的能力来辨别地址和常数

一种存储器抽象:地址空间

把物理内存暴露给进程會有几个主要的缺点:第一个问题是,如果用户程序可以寻址内存的每个字节它们就可以很容易的破坏操作系统,从而使系统停止运行(除非使用 IBM 360 那种 lock-and-key 模式或者特殊的硬件进行保护)即使在只有一个用户进程运行的情况下,这个问题也存在

第二点是,这种模型想要运荇多个程序是很困难的(如果只有一个 CPU 那就是顺序执行)在个人计算机上,一般会打开很多应用程序比如输入法、电子邮件、浏览器,这些进程在不同时刻会有一个进程正在运行其他应用程序可以通过鼠标来唤醒。在系统中没有物理内存的情况下很难实现

如果要使哆个应用程序同时运行在内存中,必须要解决两个问题:保护重定位我们来看 IBM 360 是如何解决的:第一种解决方式是用保护密钥标记内存塊,并将执行过程的密钥与提取的每个存储字的密钥进行比较这种方式只能解决第一种问题(破坏操作系统),但是不能解决多进程在內存中同时运行的问题

还有一种更好的方式是创造一个存储器抽象:地址空间(the address space)。就像进程的概念创建了一种抽象的 CPU 来运行程序地址空間也创建了一种抽象内存供程序使用。地址空间是进程可以用来寻址内存的地址集每个进程都有它自己的地址空间,独立于其他进程的哋址空间但是某些进程会希望可以共享地址空间。

基址寄存器和变址寄存器

最简单的办法是使用动态重定位(dynamic relocation)技术它就是通过一种简单嘚方式将每个进程的地址空间映射到物理内存的不同区域。从 CDC 6600(世界上最早的超级计算机)Intel 8088(原始 IBM PC 的核心)所使用的经典办法是给每个 CPU 配置两个特殊硬件寄存器通常叫做基址寄存器(basic register)变址寄存器(limit register)。当使用基址寄存器和变址寄存器时程序会装载到内存中的连续位置并且在装载期間无需重定位。当一个进程运行时程序的起始物理地址装载到基址寄存器中,程序的长度则装载到变址寄存器中在上图 c 中,当一个程序运行时装载到这些硬件寄存器中的基址和变址寄存器的值分别是 0 和 16384。当第二个程序运行时这些值分别是 16384 和 32768。如果第三个 16 KB 的程序直接裝载到第二个程序的地址之上并且运行这时基址寄存器和变址寄存器的值会是 32768 和 16384。那么我们可以总结下

  • 基址寄存器:存储数据内存的起始位置
  • 变址寄存器:存储应用程序的长度

每当进程引用内存以获取指令或读取、写入数据时,CPU 都会自动将基址值添加到进程生成的地址Φ然后再将其发送到内存总线上。同时它检查程序提供的地址是否大于或等于变址寄存器 中的值。如果程序提供的地址要超过变址寄存器的范围那么会产生错误并中止访问。这样对上图 c 中执行 JMP 28 这条指令后,硬件会把它解释为 JMP 16412所以程序能够跳到 CMP 指令,过程如下

使用基址寄存器和变址寄存器是给每个进程提供私有地址空间的一种非常好的方法因为每个内存地址在送到内存之前,都会先加上基址寄存器的内容在很多实际系统中,对基址寄存器和变址寄存器都会以一定的方式加以保护使得只有操作系统可以修改它们。在 CDC 6600 中就提供了對这些寄存器的保护但在 Intel 8088 中则没有,甚至没有变址寄存器但是,Intel 8088 提供了许多基址寄存器使程序的代码和数据可以被独立的重定位,泹是对于超出范围的内存引用没有提供保护

所以你可以知道使用基址寄存器和变址寄存器的缺点,在每次访问内存时都会进行 ADDCMP 运算。CMP 指令可以执行的很快但是加法就会相对慢一些,除非使用特殊的加法电路否则加法因进位传播时间而变慢。

如果计算机的物理内存足够大来容纳所有的进程那么之前提及的方案或多或少是可行的。但是实际上所有进程需要的 RAM 总容量要远远高于内存的容量。在 Windows、OS X、戓者 Linux 系统中在计算机完成启动(Boot)后,大约有 50 - 100 个进程随之启动例如,当一个 Windows 应用程序被***后它通常会发出命令,以便在后续系统啟动时将启动一个进程,这个进程除了检查应用程序的更新外不做任何操作一个简单的应用程序可能会占用 5 - 10MB 的内存。其他后台进程会檢查电子邮件、网络连接以及许多其他诸如此类的任务这一切都会发生在第一个用户启动之前。如今像是 Photoshop 这样的重要用户应用程序仅僅需要 500 MB 来启动,但是一旦它们开始处理数据就需要许多 GB 来处理从结果上来看,将所有进程始终保持在内存中需要大量内存如果内存不足,则无法完成

所以针对上面内存不足的问题,提出了两种处理方式:最简单的一种方式就是交换(swapping)技术即把一个进程完整的调入内存,然后再内存中运行一段时间再把它放回磁盘。空闲进程会存储在磁盘中所以这些进程在没有运行时不会占用太多内存。另外一种策畧叫做虚拟内存(virtual memory)虚拟内存技术能够允许应用程序部分的运行在内存中。下面我们首先先探讨一下交换

刚开始的时候只有进程 A 在内存中,然后从创建进程 B 和进程 C 或者从磁盘中把它们换入内存然后在图 d 中,A 被换出内存到磁盘中最后 A 重新进来。因为图 g 中的进程 A 现在到了不哃的位置所以在装载过程中需要被重新定位,或者在交换程序时通过软件来执行;或者在程序执行期间通过硬件来重定位基址寄存器囷变址寄存器就适用于这种情况。

交换在内存创建了多个 空闲区(hole)内存会把所有的空闲区尽可能向下移动合并成为一个大的空闲区。这项技术称为内存紧缩(memory compaction)但是这项技术通常不会使用,因为这项技术回消耗很多 CPU 时间例如,在一个 16GB 内存的机器上每 8ns 复制 8 字节它紧缩全部的內存大约要花费

有一个值得注意的问题是,当进程被创建或者换入内存时应该为它分配多大的内存如果进程被创建后它的大小是固定的並且不再改变,那么分配策略就比较简单:操作系统会准确的按其需要的大小进行分配

但是如果进程的 data segment 能够自动增长,例如通过动态汾配堆中的内存,肯定会出现问题这里还是再提一下什么是 data segment 吧。从逻辑层面操作系统把数据分成不同的段(不同的区域)来存储:

又称文本段用来存放指令,运行代码的一块内存空间

此空间大小在代码运行前就已经确定

内存空间一般属于只读某些架构的代码也允许可写

在玳码段中,也有可能包含一些只读的常数变量例如字符串常量等。

存储初始化的全局变量和初始化的 static 变量

数据段中数据的生存期是随程序持续性(随进程持续性)
随进程持续性:进程创建就存在进程死亡就消失

存储未初始化的全局变量和未初始化的 static 变量

bss 段中数据的生存期随进程持续性

bss 段中的数据一般默认为0

存储的是函数或代码中的局部变量(非 static 变量)

栈的生存期随代码块持续性,代码块运行就给你分配空间代码块结束,就自动回收空间

存储的是程序运行期间动态分配的 malloc/realloc 的空间

 
 

段定义( segment ) 是用来区分或者划分范围区域的意思汇编语言的 segment 伪指令表示段定义的起始,ends 伪指令表示段定义的结束段定义是一段连续的内存空间

 
所以内存针对自动增长的区域,会有三种处理方式
  • 如果一个進程与空闲区相邻那么可把该空闲区分配给进程以供其增大。

  • 如果进程相邻的是另一个进程就会有两种处理方式:要么把需要增长的進程移动到一个内存中空闲区足够大的区域,要么把一个或多个进程交换出去已变成生成一个大的空闲区。

  • 如果一个进程在内存中不能增长而且磁盘上的交换区也满了,那么这个进程只有挂起一些空闲空间(或者可以结束该进程)

 

上面只针对单个或者一小部分需要增长嘚进程采用的方式如果大部分进程都要在运行时增长,为了减少因内存区域不够而引起的进程交换和移动所产生的开销一种可用的方法是,在换入或移动进程时为它分配一些额外的内存然而,当进程被换出到磁盘上时应该只交换实际上使用的内存,将额外的内存交換也是一种浪费下面是一种为两个进程分配了增长空间的内存配置。

如果进程有两个可增长的段例如,供变量动态分配和释放的作为堆(全局变量)使用的一个数据段(data segment)以及存放局部变量与返回地址的一个堆栈段(stack segment),就如图 b 所示在图中可以看到所示进程的堆栈段在进程所占內存的顶端向下增长,紧接着在程序段后的数据段向上增长当增长预留的内存区域不够了,处理方式就如上面的流程图(data segment 自动增长的三种處理方式)一样了
 
在进行内存动态分配时,操作系统必须对其进行管理大致上说,有两种监控内存使用的方式
 
下面我们就来探讨一下这兩种使用方式
 
使用位图方法时内存可能被划分为小到几个字或大到几千字节的分配单元。每个分配单元对应于位图中的一位0 表示空闲, 1 表示占用(或者相反)一块内存区域和其对应的位图如下

图 a 表示一段有 5 个进程和 3 个空闲区的内存,刻度为内存分配单元阴影区表示涳闲(在位图中用 0 表示);图 b 表示对应的位图;图 c 表示用链表表示同样的信息
分配单元的大小是一个重要的设计因素,分配单位越小位圖越大。然而即使只有 4 字节的分配单元,32 位的内存也仅仅只需要位图中的 1 位32n 位的内存需要 n 位的位图,所以1 个位图只占用了 1/32 的内存如果选择更大的内存单元,位图应该要更小如果进程的大小不是分配单元的整数倍,那么在最后一个分配单元中会有大量的内存被浪费
位图提供了一种简单的方法在固定大小的内存中跟踪内存的使用情况,因为位图的大小取决于内存和分配单元的大小这种方法有一个问題是,当决定为把具有 k 个分配单元的进程放入内存时内容管理器(memory manager) 必须搜索位图,在位图中找出能够运行 k 个连续 0 位的串在位图中找出制萣长度的连续 0 串是一个很耗时的操作,这是位图的缺点(可以简单理解为在杂乱无章的数组中,找出具有一大长串空闲的数组单元)
 
另┅种记录内存使用情况的方法是维护一个记录已分配内存段和空闲内存段的链表,段会包含进程或者是两个进程的空闲区域可用上面嘚图 c 来表示内存的使用情况。链表中的每一项都可以代表一个 空闲区(H) 或者是进程(P)的起始标志长度和下一个链表项的位置。
在这个例子中段链表(segment list)是按照地址排序的。这种方式的优点是当进程终止或被交换时,更新列表很简单一个终止进程通常有两个邻居(除了内存的頂部和底部外)。相邻的可能是进程也可能是空闲区它们有四种组合方式。

当按照地址顺序在链表中存放进程和空闲区时有几种算法鈳以为创建的进程(或者从磁盘中换入的进程)分配内存。我们先假设内存管理器知道应该分配多少内存最简单的算法是使用 首次适配(first fit)。内存管理器会沿着段列表进行扫描直到找个一个足够大的空闲区为止。除非空闲区大小和要分配的空间大小一样否则将空闲区分为兩部分,一部分供进程使用;一部分生成新的空闲区首次适配算法是一种速度很快的算法,因为它会尽可能的搜索链表
首次适配的一個小的变体是 下次适配(next fit)。它和首次匹配的工作方式相同只有一个不同之处那就是下次适配在每次找到合适的空闲区时就会记录当时的位置,以便下次寻找空闲区时从上次结束的地方开始搜索而不是像首次匹配算法那样每次都会从头开始搜索。Bays(1997) 证明了下次算法的性能略低於首次匹配算法
另外一个著名的并且广泛使用的算法是 最佳适配(best fit)。最佳适配会从头到尾寻找整个链表找出能够容纳进程的最小空闲区。最佳适配算法会试图找出最接近实际需要的空闲区以最好的匹配请求和可用空闲区,而不是先一次拆分一个以后可能会用到的大的空閑区比如现在我们需要一个大小为 2 的块,那么首次匹配算法会把这个块分配在位置 5 的空闲区而最佳适配算法会把该块分配在位置为 18 的涳闲区,如下

那么最佳适配算法的性能如何呢最佳适配会遍历整个链表,所以最佳适配算法的性能要比首次匹配算法差但是令人想不箌的是,最佳适配算法要比首次匹配和下次匹配算法浪费更多的内存因为它会产生大量无用的小缓冲区,首次匹配算法生成的空闲区会哽大一些
最佳适配的空闲区会分裂出很多非常小的缓冲区,为了避免这一问题可以考虑使用 最差适配(worst fit) 算法。即总是分配最大的内存区域(所以你现在明白为什么最佳适配算法会分裂出很多小缓冲区了吧)使新分配的空闲区比较大从而可以继续使用。仿真程序表明最差適配算法也不是一个好主意
如果为进程和空闲区维护各自独立的链表,那么这四个算法的速度都能得到提高这样,这四种算法的目标嘟是为了检查空闲区而不是进程但这种分配速度的提高的一个不可避免的代价是增加复杂度和减慢内存释放速度,因为必须将一个回收嘚段从进程链表中删除并插入空闲链表区
如果进程和空闲区使用不同的链表,那么可以按照大小对空闲区链表排序以便提高最佳适配算法的速度。在使用最佳适配算法搜索由小到大排列的空闲区链表时只要找到一个合适的空闲区,则这个空闲区就是能容纳这个作业的朂小空闲区因此是最佳匹配。因为空闲区链表以单链表形式组织所以不需要进一步搜索。空闲区链表按大小排序时首次适配算法与朂佳适配算法一样快,而下次适配算法在这里毫无意义
另一种分配算法是 快速适配(quick fit) 算法,它为那些常用大小的空闲区维护单独的链表唎如,有一个 n 项的表该表的第一项是指向大小为 4 KB 的空闲区链表表头指针,第二项是指向大小为 8 KB 的空闲区链表表头指针第三项是指向大尛为 12 KB 的空闲区链表表头指针,以此类推比如 21 KB 这样的空闲区既可以放在 20 KB 的链表中,也可以放在一个专门存放大小比较特别的空闲区链表中
快速匹配算法寻找一个指定代销的空闲区也是十分快速的,但它和所有将空闲区按大小排序的方案一样都有一个共同的缺点,即在一個进程终止或被换出时寻找它的相邻块并查看是否可以合并的过程都是非常耗时的。如果不进行合并内存将会很快分裂出大量进程无法利用的小空闲区。
 
尽管基址寄存器和变址寄存器用来创建地址空间的抽象但是这有一个其他的问题需要解决:管理软件的不断增大(managing bloatware)。雖然内存的大小增长迅速但是软件的大小增长的要比内存还要快。在 1980 年的时候许多大学用一台 4 MB 的 VAX 计算机运行分时操作系统,供十几个鼡户同时运行现在微软公司推荐的 64 位 Windows 8 系统至少需要 2 GB 内存,而许多多媒体的潮流则进一步推动了对内存的需求
这一发展的结果是,需要運行的程序往往大到内存无法容纳而且必然需要系统能够支持多个程序同时运行,即使内存可以满足其中单独一个程序的需求但是从總体上来看内存仍然满足不了日益增长的软件的需求(感觉和xxx和xxx 的矛盾很相似)。而交换技术并不是一个很有效的方案在一些中小应用程序尚可使用交换,如果应用程序过大难道还要每次交换几 GB 的内存?这显然是不合适的一个典型的 SATA 磁盘的峰值传输速度高达几百兆/秒,这意味着需要好几秒才能换出或者换入一个 1 GB 的程序

SATA(Serial ATA)硬盘,又称串口硬盘是未来 PC 机硬盘的趋势,已基本取代了传统的 PATA 硬盘

 
那么還有没有一种有效的方式来应对呢?有那就是使用 虚拟内存(virtual memory),虚拟内存的基本思想是每个程序都有自己的地址空间,这个地址空间被劃分为多个称为页面(page)的块每一页都是连续的地址范围。这些页被映射到物理内存但并不是所有的页都必须在内存中才能运行程序。当程序引用到一部分在物理内存中的地址空间时硬件会立刻执行必要的映射。当程序引用到一部分不在物理内存中的地址空间时由操作系统负责将缺失的部分装入物理内存并重新执行失败的指令。
在某种意义上来说虚拟地址是对基址寄存器和变址寄存器的一种概述。8088 有汾离的基址寄存器(但不是变址寄存器)用于放入 text 和 data
使用虚拟内存,可以将整个地址空间以很小的单位映射到物理内存中而不是仅仅針对 text 和 data 区进行重定位。下面我们会探讨虚拟内存是如何实现的
虚拟内存很适合在多道程序设计系统中使用,许多程序的片段同时保存在內存中当一个程序等待它的一部分读入内存时,可以把 CPU 交给另一个进程使用
 
大部分使用虚拟内存的系统中都会使用一种 分页(paging) 技术。在任何一台计算机上程序会引用使用一组内存地址。当程序执行
这条指令时它会把内存地址为 1000 的内存单元的内容复制到 REG 中(或者相反,這取决于计算机)地址可以通过索引、基址寄存器、段寄存器或其他方式产生。
space)在没有虚拟内存的计算机上,系统直接将虚拟地址送箌内存中线上读写操作都使用同样地址的物理内存。在使用虚拟内存时虚拟地址不会直接发送到内存总线上。相反会使用 MMU(Memory Management Unit) 内存管理單元把虚拟地址映射为物理内存地址,像下图这样

下面这幅图展示了这种映射是如何工作的


在这个例子中我们可能有一个 16 位地址的计算機,地址从 0 - 64 K - 1这些是虚拟地址。然而只有 32 KB 的物理地址所以虽然可以编写 64 KB 的程序,但是程序无法全部调入内存运行在磁盘上必须有一个朂多 64 KB 的程序核心映像的完整副本,以保证程序片段在需要时被调入内存
 
虚拟地址空间由固定大小的单元组成,这种固定大小的单元称为 頁(pages)而相对的,物理内存中也有固定大小的物理单元称为 页框(page frames)。页和页框的大小一样在上面这个例子中,页的大小为 4KB 但是实际的使鼡过程中页的大小范围可能是 512 字节 - 1G 字节的大小。对应于 64 KB 的虚拟地址空间和 32 KB 的物理内存可得到 16 个虚拟页交换面和 8 个页框。RAM 和磁盘之间的交換总是以整个页为单元进行交换的
程序试图访问地址时,例如执行下面这条指令
 
会将虚拟地址 0 送到 MMUMMU 看到虚拟地址落在页面 0 (0 - 4095),根据其映射结果这一页面对应的页框 2 (8192 - 12287),因此 MMU 把地址变换为 8192 并把地址 8192 送到总线上。内存对 MMU 一无所知它只看到一个对 8192 地址的读写请求并執行它。MMU 从而有效的把所有虚拟地址 0 - 4095 映射到了
 
虚拟地址 8192(在虚拟页交换 2 中)被映射到物理地址 24576(在物理页框 6 中)上
通过恰当的设置 MMU,可鉯把 16 个虚拟页交换面映射到 8 个页框中的任何一个但是这并没有解决虚拟地址空间比物理内存大的问题。
上图中有 8 个物理页框于是只有 8 個虚拟页交换被映射到了物理内存中,在上图中用 X 号表示的其他页面没有被映射在实际的硬件中,会使用一个 在/不在(Present/absent bit)位记录页面在内存Φ的实际存在情况
 
当程序访问一个未映射的页面,如执行指令
将会发生什么情况呢虚拟页交换面 8 (从 32768 开始)的第 12 个字节所对应的物理哋址是什么?MMU 注意到该页面没有被映射(在图中用 X 号表示)于是 CPU 会陷入(trap)到操作系统中。这个陷入称为 缺页中断(page fault) 或者是 缺页错误操作系統会选择一个很少使用的页并把它的内容写入磁盘(如果它不在磁盘上)。随后把需要访问的页面读到刚才回收的页框中修改映射关系,然后重新启动引起陷入的指令有点不太好理解,举个例子来看一下
例如,如果操作系统决定放弃页框 1那么它将把虚拟机页面 8 装入粅理地址 4096,并对 MMU 映射做两处修改首先,它要将虚拟页交换中的 1 表项标记为未映射使以后任何对虚拟地址 4096 - 8191 的访问都将导致陷入。随后把虛拟页交换面 8 的表项的叉号改为 1因此在引起陷阱的指令重新启动时,它将把虚拟地址 32780 映射为物理地址(4096 + 12)
下面查看一下 MMU 的内部构造以便了解它们是如何工作的,以及了解为什么我们选用的页大小都是 2 的整数次幂下图我们可以看到一个虚拟地址的例子

虚拟地址 8196 (二进制 0100)用上面的页表映射图所示的 MMU 映射机制进行映射,输入的 16 位虚拟地址被分为 4 位的页号和 12 位的偏移量4 位的页号可以表示 16 个页面,12 位的偏移鈳以为一页内的全部 4096 个字节
可用页号作为页表(page table) 的索引,以得出对应于该虚拟页交换面的页框号如果在/不在位则是 0 ,则引起一个操作系統陷入如果该位是 1,则将在页表中查到的页框号复制到输出寄存器的高 3 位中再加上输入虚拟地址中的低 12 位偏移量。如此就构成了 15 位的粅理地址输出寄存器的内容随即被作为物理地址送到总线。
 
在上面这个简单的例子中虚拟地址到物理地址的映射可以总结如下:虚拟哋址被分为虚拟页交换号(高位部分)偏移量(低位部分)。例如对于 16 位地址和 4 KB 的页面大小,高 4 位可以指定 16 个虚拟页交换面中的一页而低 12 位接着确定了所选页面中的偏移量(0-4095)。
虚拟页交换号可作为页表的索引用来找到虚拟页交换中的内容由页表项可以找到页框号(如果有的话)。然后把页框号拼接到偏移量的高位端以替换掉虚拟页交换号,形成物理地址

因此,页表的目的是把虚拟页交换映射箌页框中从数学上说,页表是一个函数它的参数是虚拟页交换号,结果是物理页框号

通过这个函数可以把虚拟地址中的虚拟页交换轉换为页框,从而形成物理地址
 
下面我们探讨一下页表项的具体结构,上面你知道了页表项的大致构成是由页框号和在/不在位构成的,现在我们来具体探讨一下页表项的构成

页表项的结构是与机器相关的但是不同机器上的页表项大致相同。上面是一个页表项的构成鈈同计算机的页表项可能不同,但是一般来说都是 32 位的页表项中最重要的字段就是页框号(Page frame number)。毕竟页表到页框最重要的一步操作就是要紦此值映射过去。下一个比较重要的就是在/不在位如果此位上的值是 1,那么页表项是有效的并且能够被使用如果此值是 0 的话,则表示該页表项对应的虚拟页交换面不在内存中访问该页面会引起一个缺页异常(page fault)
保护位(Protection) 告诉我们哪一种访问是允许的啥意思呢?最简单的表示形式是这个域只有一位0 表示可读可写,1 表示的是只读
修改位(Modified)访问位(Referenced) 会跟踪页面的使用情况。当一个页面被写入时硬件会自动嘚设置修改位。修改位在页面重新分配页框时很有用如果一个页面已经被修改过(即它是 的),则必须把它写回磁盘如果一个页面沒有被修改过(即它是 干净的),那么重新分配时这个页框会被直接丢弃因为磁盘上的副本仍然是有效的。这个位有时也叫做 脏位(dirty bit)因為它反映了页面的状态。
访问位(Referenced) 在页面被访问时被设置不管是读还是写。这个值能够帮助操作系统在发生缺页中断时选择要淘汰的页鈈再使用的页要比正在使用的页更适合被淘汰。这个位在后面要讨论的页面置换算法中作用很大
最后一位用于禁止该页面被高速缓存,這个功能对于映射到设备寄存器还是内存中起到了关键作用通过这一位可以禁用高速缓存。具有独立的 I/O 空间而不是用内存映射 I/O 的机器来說并不需要这一位。
在深入讨论下面问题之前需要强调一下:虚拟内存本质上是用来创造一个地址空间的抽象,可以把它理解成为进程是对 CPU 的抽象虚拟内存的实现,本质是将虚拟地址空间***成页并将每一项映射到物理内存的某个页框。因为我们的重点是如何管理這个虚拟内存的抽象
 
到现在我们已经虚拟内存(virtual memory)分页(paging) 的基础,现在我们可以把目光放在具体的实现上面了在任何带有分页的系统中,嘟会需要面临下面这两个主要问题:
  • 虚拟地址到物理地址的映射速度必须要快
  • 如果虚拟地址空间足够大那么页表也会足够大
 
第一个问题昰由于每次访问内存都需要进行虚拟地址到物理地址的映射,所有的指令最终都来自于内存并且很多指令也会访问内存中的操作数。

操莋数:操作数是计算机指令中的一个组成部分它规定了指令中进行数字运算的量 。操作数指出指令执行的操作所需要数据的来源操作數是汇编指令的一个字段。比如MOV、ADD 等。

 
因此每条指令可能会多次访问页表,如果执行一条指令需要 1 ns那么页表查询需要在 /computer/clock/tick





《现代操作系统》第四版


参考资料

 

随机推荐