1、操作系统内存管理——分段


版权声明:本文为博主原创文章,转载请注明出处。

参考哈工大李治军老师公开课。


内存的使用

计算机对于内存的使用:将程序放在内存中,PC指向开始地址,执行指令,过程如下:

1、 先找到程序的入口地址,读取磁盘上的程序,并找一段内存的空闲区域,将程序装进内存中。

2、 重定位,将程序中的逻辑地址和程序实际放在内存中的位置(进程的PCB中)相结合,得到程序在内存中的实际地址,并将其赋给PC指针(一个程序计数器,记录指令执行的地址)。(载入运行程序时执行重定位,如果在编译时重定位,那么程序只能存放在内存的固定位置)

3、 通过PC指针找到指令,执行指令。

 

 

程序分段:

动机与实现原理:

在程序中操作系统并不会把程序整块载入内存,因为一个程序包含了许多数据结构,不能一概而论。例如程序的代码是只读的,相对固定的;而数据是会随着程序的运行动态变化的

图一:内存分段原因

所以在在内存把程序载入内存中时,会采用分段的方式进行加载,不同的程序段使用不同的存储形式,简单的说就是对于不同的程序块,留不同的空闲空间,分开访问。例如代码段一般是只读的不会增长,那么就不留空闲空间。而动态数组段就留一个较多的空闲空间,因为需要动态增长。如果不采用分段,那么当动态数组不断增长,超过了原来分配的空间,那么就必须把整个程序拷贝到另一个更大的空间。这个无疑是浪费空间和时间的,如果仅仅是把动态函数的那段移动到更大的空间,这样效率会有很大的提高,并且使内存的管理更加精确。那么定位具体的指令(数据)的地址就可以修改为:<段号,段内偏移>。例子如图:

图二:分段的实现原理

具体实现:(LDT表,就是一张二维表,图二中的那张表)

在操作系统中有两个表GDT(也是一张二维表,只是记录的信息与LDT略有不同)表和LDT表,GDT表存储在操作系统程序中,LDT表存储在运行在操作系统中的PCB中;GDT表存储了操作系统的进程段表,并且存储了指向LDT表的指针,LDT表就只存储了本进程的进程段表。


图三

 

每段在内存中的分配(动态分配)

对于内存管理,操作系统需要维护两张表,一张是空闲分区表,一张是已分配分区表,具体示例如图:


图四

对于分区的分配过程较为简单,在此我就以一组图例进行展示:


图五

 

图六

 

关于新申请空间的分配问题:

当提出段申请的时候,例如对于图六,需要申请一个40K的段,那么就有3中分配方式。

1、 首先适配:直接顺序查询空闲分配表,只要装得下,就分配一块。

2、 最佳适配:就是遍历表,找到比需要空间大或者相等的,且两者大小最接近的空闲空间,但是这种方式会留下极小的空间,不便处理。

3、 最差适配:查询空间表,找到最大的空闲空间,然后分配一块出来。

 

当然,这种分配方式是有问题的,就是必须找一个>=目标区域的空间,但是这样分配的空间就难免出现一些内存空间没法使用,导致浪费;一种解决方法是定期把使用过的空间挪到一堆,把空着的空间集中到一起。当然这种方式有两个问题:1、挪到空间需要花费时间,在此期间计算机不能正常使用;2、把数据和代码挪到一起了,不利于数据段的动态增长。

智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告