Notes on Understanding the Linux Kernel

原创 2015年11月19日 17:30:11

第六章内存管理

RAM中一部分永久保存了内核代码和内核静态数据结构。而剩余部分就是动态内存。系统的性能取决于如何有效管理动态内存。
本章通过三部分内容介绍内核分配动态内存。“页框管理”和“内存区管理”两节分别介绍两种对连续物理内存区处理的技术。“非连续内存区管理”一节介绍了处理不连续的内存区。


页框管理

Intel的奔腾处理器采用两种不同的页框大小,4k和4M。Linux采用4KB页框大小作为标准的内存分配单元

  • 分页单元可以自动检测正在被访问的页是否包含在某个页框中。通过使用指向页框的页表项中的标识,每个页框是受硬件保护的。选用4KB作为分配单元,内核就可以直接确定发生缺页异常的页所在的内存分配单元。
  • 4KB是大部分磁盘块大小的倍数,因此在主存和磁盘之间传输数据可以更加高效。管理4KB比管理4MB的数据更加容易。

内核必须记录每个页框当前的状态。例如,内核必须能区分哪些页框包含的是属于进程的页,而哪些页框包含的是内核代码或内核数据。同理,内核还必须能够确定动态内存中页框是否空闲。这种状态信息被保存在一个描述符数组中,每个页框对应数组中的一个元素。

伙伴系统算法

内核应该分配一组连续的页框而建立一种稳定的、高效的分配策略。

外碎片问题
频繁的请求和释放不同大小的连续页框,必然导致在已分配页框的块内分散许多小块的空闲页框。由此带来的问题是,即使有足够的空闲页框可以满足请求,但要分配一个大块的连续页框就可能无法满足。

避免外碎片的两种方法:

  • 利用分页单元把一组非连续的空闲页框映射到连续的线性地址区间
  • 开发一种适当的技术来记录先出你的空闲连续页框块的情况,以尽量避免为满足对小块的请求而把大块的空闲块进行分割。

内核选择第二种方法,基于以下原因:

  • 在某些情况下,由于连续的线性地址不足以满足请求,因此连续的页框确实是必要的。典型例子是,请求内存给DMA处理器分配缓冲,DMA忽略分页单元二直接访问地址总线,因此,在单独的IO操作中传送几个磁盘山区的数据时,所请求的缓冲就必须位于连续的页框。

  • 即使连续的页框分配不是很必要,但它在保持内核页表不变方面所起的作用也是不容忽视的。频繁的修改页表,势必导致平均访问内存的次数增加,这会使得CPU频繁的刷新TLB。

Linux采用伙伴算法来解决外碎片问题,把所有的空闲页框分组为10块链表,每块链表包括1,2,4,8,16,32,64,128,512连续的页框。每个块的第一个页框的物理地址是该块大小的整数倍。

数据结构

Linux使用两种不同的伙伴算法:一种适合 ISA DMA的页框,另一种处理其他页框。

内存区管理

内存区,具有连续的物理地址和任意长度的内存单元。
伙伴算法采用页框作为基本内存区,适用于大块内存的请求。对于小内存区,采用一种全新的数据结构,来描述在同一页框内如何分配小内存。

内碎片问题
请求内存的大小与分配的大小不匹配造成的。

slab分配器

  • slab分配器把内存区看做对象,这个对象由一个数据结构和构造和解析函数组成,前者初始化内存区,后者回收内存区。为了避免重复初始化对象,slab分配器并不丢弃已分配的对象,而是释放但是保存在内存区中。当以后要请求新的对象时,就可以从内存中获取而不用重新初始化。
    实际上Linux对内存区的管理并不需要进行初始化或者回收,指向构造和析构这两个方法的指针都为null。

  • 内核函数倾向于反复请求同一类型的内存区。内核创建一个新进程,为进程描述符分配内存区。内核将这些页框保存在高速缓存中并重新使用。

  • 内存区的请求可以根据访问的频繁度来分类。硬件高速缓存的使用,尽可能限制对伙伴系统算法的调用:每次调用都会弄脏硬件高速缓存,因此增加了对内存的平均访问次数。

通用和专用高速缓存

高速缓存被分为两种类型:通用和专用。通用高速缓存只由slab分配器用于自己的目的,而专用高速缓存由内核的其他部分使用。

  • 第一个高速缓存包含由内核使用的其余高速缓存的高速缓存描述符。
  • 第二个高速缓存包含没有存放在slab内的slab描述符。
  • 另外的十三个高速缓存包含集合分布的额内存区。

在系统初始化期间调用kmem_chche_init()和kmem_cache_sizes_init()来建立通用高速缓存。

专用高速缓存是由kmem_cache_create()函数创建的。这个函数首先根据参数确定处理新高速缓存的最佳方法。一旦一个高速缓存被创建,就不能撤销它。

所有通用和专用高速缓存的名字都可以在运行期间读取proc/slabinfo文件得到。这个文件也说明每个高速缓存中空闲对象的个数和已分配对象的个数。

给高速缓存分配slab

一个新建的高速缓存没有包含任何slab,因此也没有空闲的对象。只有当以下两个条件为真时,才给高速缓存分配slab:

  • 已发出一个分配新对象的请求。
  • 高速缓存不包含任何空闲对象。

从高速缓存中释放slab

slab分配器不能靠自己释放空slab中的页框。事实上,只有在下列条件成立的情况下才能释放slab:
- 伙伴系统不能满足新请求的一组页框
- slab为空,slab中包含的所有对象都是空闲的。

非连续内存区管理

把内存区映射到一组连续的页框是最好的选择,这样会充分得利用高速缓存并达到较低的平均访问时间。如果对内存区的请求不是很频繁,通过连续的线性地址来访问非连续的页框的一种分配模式就很有意义,这种模式的优点是避免了外碎片,而缺点是必须打乱内核页表。非连续内存区的大小必须是4096的倍数。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

understanding the linux kernel

这本书买了有3个月了,一直没敢看,怕自己看不懂。最近实在不想看别的书籍了,于是拿起了这本书 书中,代码比较少,不像赵炯的那本书,全是代码 我看的是第三版,中国电力出版社翻译的。 第一章: 1. 自旋锁...

Understanding the Linux Kernel (3rd)

  • 2009年05月29日 12:26
  • 2.76MB
  • 下载

Understanding The Linux Kernel 3rd.pdf

  • 2007年12月29日 14:37
  • 7.37MB
  • 下载

Linux Kernel Development (2nd) - Study Notes

It is important to initialize hardware and register an interrupt handler in the proper order to prev...

Understanding the Linux Kernel 3rd Edition

  • 2008年07月30日 12:52
  • 2.79MB
  • 下载

Linux Kernel Notes

LDK NOTES 『』表示着重注意的部分   2.1, cpu运行在三种状态:             内核空间的进程上下文             内核空间的中断上下文    ...

Trick on the Version Magic Number of Linux Kernel

Trick on the Verson Magic Number of Linux KernelMAR 15TH, 2013 | COMMENTSRecently, I was working on...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Notes on Understanding the Linux Kernel
举报原因:
原因补充:

(最多只允许输入30个字)