(十二)内存管理
内核本身不能像用户空间那样奢侈地使用内存。内核与用户空间不同,它不具备这种能力,它不支持简单便捷地内存分配方式。
页
内核把物理页作为内存管理的基本单位。尽管处理器的最小可寻址单位通常为字,但是,内存管理单元通常以页为单位进行处理。
内核用struct page结构表示系统中的每个物理页,page结构与物理页相关,而并非与虚拟页相关。因此,该结构对页的描述只是短暂的。即使页中所包含的数据继续存在,由于交换等原因,它们也可能并不再和同一个page结构相关联。内核仅仅用这个数据结构来描述当前时刻在相关的物理页中存放的东西。这种数据结构的目的在于描述物理内存本身,而不是描述包含在其中的数据。
区
由于硬件的限制,内核并不能对所有的页一视同仁。有些页位于内存中特定的物理地址上,所以不能将其用于一些特定的任务。由于存在这种限制,所以内核把页划分为不同的区。
一些硬件只能用某些特定的内存地址来执行DMA(直接内存访问);一些体系结构的内存的物理寻址范围比虚拟寻址范围大得多,这样,就有一些内存不能永久地映射到内核空间上。因为存在这些制约条件,Linux主要使用四种区:ZONE_DMA、ZONE_DMA32、ZONE_NORMAL、ZONE_HIGHMEM。
ZONE_DMA:包含的页用来执行DMA操作。
ZONE_DMA32:只能被32位设备访问执行DMA操作。
ZONE_NORMAL:能正常映射的页。
ZONE_HIGHMEM:不能永久映射到内核地址空间的页。
区的划分没有任何物理意义,这只是内核为了管理页而采取的一种逻辑上的分组。
如果可供分配的资源不够用了,内核就会去占用其他可用区的内存。
slab层
分配和释放数据结构是所有内核中最普遍的操作之一。为了便于数据的频繁分配和回收,编程人员常常会用到空闲链表。空闲链表包含可供使用的、已经分配好的数据结构块。当代码需要一个新的数据结构实例时,就可以从空闲链表中抓取一个,而不需要分配内存,再把数据放进去。以后,当不再需要这个数据结构的实例时,就把它放回空闲链表,而不是释放它。从这个意义上说,空闲链表相当于对象高速缓存——快速存储频繁使用的对象类型。