因仑“3+1”工程特种兵精英论坛

标题: 对操作系统内存管理的模拟(原理) [打印本页]

作者: XJzy    时间: 2015-9-28 00:12
标题: 对操作系统内存管理的模拟(原理)
对操作系统内存管理的模拟(原理)
在刚过去的最近的一段时间,老师在讲linux内存管理,她让我们每周都写周报告,看来她是用管理研究生的方式来对付我们了。哎,没办法,人在屋檐下,不得不低头,谁让咱是人家的学生捏。

  其实老师也是对大家的一个督促,渐渐地,我发现,其实也周报告有一个好处就是把以前自己不太关注的问题摆到台面上,使自己对一个老的问题有了新的认识,这样其实也是不错的,还是非常感谢老师的良苦用心。

  下面我将我对内存管理的一些问题的理解列出来,如果你看了之后有什么不同意见,可以留言给我,我很期待你的意见或者建议,上次写了一个ARM串行通信的例子,结果没人留言,不知道为什么,园子里没人做这方面的工作吗?对此表示怀疑,呵呵...

  我是按照一问一答的形式进行的,所以在这也就这样了,最近心情起伏比较大,见谅。老师说做学问最忌讳的是摘抄不指明出处,所以我说明一下,一些这些总结是我从计算机的心智上总结归纳出来的,要是现在不说以后有人告发我,说我抄袭怎么办。

1.为什么要进行内存管理?
CPU需要两种信息:数据和代码,这些数据存放在内存,操作系统要控制CPU的运行,就要对内存进行管理。

2.几个难以区分的概念
用户空间 地址空间 进程空间 内核空间 虚拟内存(虚拟地址空间)
进程空间:进程所要的所有资源
内核空间:供内核使用的空间
虚拟内存:每个进程可以通过系统调用进入内核,所以内核空间其实是所有进程共享,从进程角度看,每个进程都可拥有4GB的虚拟地址空间(目前)

3.内存管理的目标
地址保护:一个程序不能访问另一个程序地址空间
地址独立:程序发出的地址应与物力主存地址无关

4.多道编程的内存管理
多道编程环境下,无法将程序加到固定的内存地址上,即:无法使用静态地址翻译,这就需要动态地址翻译

虚拟地址                    物理地址
用户进程——————>地址翻译器——————>物理内存

5.地址翻译的方法
一个程序是加载到内存事先划分好的某片区域,而且该程序是整个加在进去
物理地址 = 虚拟地址 + 程序所在区域的起始地址
多个程序需要地址保护,并进行合法访问

合法访问条件:程序所在区域起始地址<=有效地址<=程序所在区域起始地址 + 程序长度

动态地址翻译的优点:
1.灵活
2. 保护地址
3.实现虚拟内存

6. 内存管理方法
固定加载地址  固定分区  分固定分区  交换

7.页式内存管理
内存管理出现的问题:空间浪费   程序大小受限
页式内存管理克服外部碎片,增大程序的可用空间

8. 分页系统的优缺点
优点:
i.不产生外部碎片
ii.可以共享小的地址

缺点:
1.1.页表很大,占用空间
2.降低系统速度

9. 为什么要进行页面更换
不是因为一个页面过时而找一个新的页面来替换,而是因为需要使用新的页面而找一个过时的页面作为替换牺牲品

更换原则:
a) 最好是再也不会访问的页面
b) 选择一个没有修改过的页面

10.  页面更换算法
1.随机更换算
2.先进先出算
3.最有更换算法(判断算法优劣标准)
4.NRU(Not Recent Used)算法
5.LUR(Least Recent Used)算法

11.  为什么提出段式内存管理?
由于分页系统的缺点
分段管理实际是基本内存管理的一般化,而基本内存管理是分段管理的特例

12.  分段的优缺点
优点:
1.1.1.每个逻辑单元可独享一个虚拟地址空间,使编程空间大增
2.共享方便
3.对空间稀疏的程序,节省大量空间

缺点:
i. 产生外部碎片
ii. 一个段必须全部加载到内存

13.  为什么要使用段页式进行内存管理?
将分段和分页组合使用,同时获得分段和分页的好处,但又避免了单独分段和分页的缺陷
对操作系统内存管理的模拟(应用)
今天来续写,觉得昨天那种安排不合理,于是将原理与应用分两篇来写,不至于让大家和我看的有些烦。

  温故而知新可以为师矣,如果不能为师,给自己当老师也不错哦。好了,写一个模拟内存管理的程序吧,老师说有原理,也要有具体实现,这是提升分析问题的一种途径。下面写写程序,并进行解说,这个程序我当时也完善了一下,其实这个程序是老师给了框架,我们实现了其中的内容。

  先写一些宏定义和全局变量

复制代码


哦,以前写的时候就有注释,所以碰到一些注释不明确的我在解释解释。

  下面是几个重要的数据结构,看过linux内核代码的童鞋对操作系统的数据结构应该有所了解,其实也就是比我们平时用的更深入、更精巧而已,基本原理还是一样,有些只是我们没那么用过,我这个还是一般的用法。

复制代码


linux内核也是这样命名的,基本都能见名知意,我就不费话了。

复制代码


写过单片机或者ARM程序的同学可能对初始化有比较深刻的理解,因为在做一些事情之前,总是要做一些准备工作,举个最简答的例子,吃饭之前要做什么准备工作,洗手?错了,我说的不是这个。吃饭你得有筷子、碗和饭菜,这些就是初始化工作,接下来你才能吃饭呀。

复制代码


这个相当于菜单,就这样。

复制代码


这个其实也相当于初始化,只不过你有了选择权。


复制代码


这段是按三种排序算法进行内存整理,如果你了解这三种排序算法,就没必要看这些了,我觉得只要对算法核心思想理解了,写基本是没问题的,最大的差异可能就是效率和风格。


复制代码


这部分主要是创建线程并作一些初始化工作。


复制代码


这部分主要是如何去分配内存,下面的代码是在碰到还有内存时,但这些内存大小都不足以满足所要申请的大小,我们就要进行碎片整理,如果整理后还不能满足要求,我们只能对程序说声对不起。


复制代码


上面就是碎片整理的代码。
下面介绍杀死一个进程并对其内存空间的释放与回收:

复制代码


好了,再来一个最原始的显示内存使用情况的界面吧。


复制代码


主函数是最简单的,也相当于一个菜单。








欢迎光临 因仑“3+1”工程特种兵精英论坛 (http://bbs.enlern.com/) Powered by Discuz! X3.4