Linux内存管理
为什么要有内存管理
如果没有内存管理机制,那么会使内存的使用效率非常低,必须要足够大的存储空间才可以满足代码的运行,如果稍有不胜就会引起程序的崩溃,对于操作系统而言,经常会需要对内存空间的切换和地址的大范围的跳转,比如代码的重定向等,没有MMU那么是无法在处理器中跑像Linux这些大型的操作系统的。举个简单的例子,如果现在一段程序运行在0~20M的存储空间上,另一段程序运行在20~50M这段存储空间上,如果运行在0~20M存储空间的代码需要访问20~50M内存空间的数据,如果没有MMU将会导致程序的崩溃,因此,内存管理对于操作系统而言是必须需要有的。
内存管理主要解决如下几个问题
1.进程地址之间的隔离,即运行时相互不影响
2.提高内存的使用效率
3.运行时重定位
4.分段分页机制
5.高速缓存机制
6.虚拟内存机制
内存管理原理
Linux内存管理的最小单位为一个页框,即4KB,Linux使用页描述来保存页框的状态信息,采用虚拟存储器技术来管理内存,虚拟地址到物理地址通过一定的转换可以得到,对于用户而言,只需要关注虚拟地址即可,Linux的MMU管理可以自动实现虚拟地址到物理地址的转换。主要的方式就是分段和分页机制:
分段机制:
就是每段程序所运行的虚拟地址时唯一的,而物理地址不去care,这样可以保证不会引起重定位问题,但是效率还是很低下的,必须要以程序为单位进行内存的操作,当内存不足时,还是需要进行磁盘数据的交换和读取,这样的IO操作是非常消耗时间的,因此需要更好的内存管理机制,不以程序为单位进行操作,而是以更小的单位进行内存的操作,因而有了著名的伙伴系统算法和slab内存分配机制,这些算法有效的解决了内存的碎片化问题。
伙伴系统原理就是把所有空闲页框分组为11个块链表,每个块链表分别包含大小为1,2,4,8,16,32,64,128,256,512,1024个连续的页框,算法会根据申请的内存大小选择合理的空闲块,并且进行管理,比如现在要申请256个页框的块,首先会寻找是否有一个256个页框的空闲块,如果没有,则选择512个页框的空闲块,一半用于满足请求,一半插到256个页框的链表中,以此类推。
伙伴系统是采用页框作为基本内存区,这适合于对大块内存的请求,但是,内核如何处理对一些数据结构分配内存空间,大多数数据结构根本占用不到一个页框。我们如何处理对小内存区的请求呢,比如说几十或几百个字节,因此又有了slab分配器,主要是解决小内存请求问题,避免碎片化。
内存管理区分为三种:
1.ZONE_DMA
2.ZONE_NORMAL
3.ZONE_HIGHMEM
ZONE_DMA和ZONE_NORMAL这两个管理区映射到线性地址空间3GB以上,内核可以直接访问,ZONE_HIGHMEM不能由内核直接访问