Linux内核探讨-- 第七章

来源:互联网 发布:公元前后的划分 知乎 编辑:程序博客网 时间:2024/05/20 13:14

文是个人分析《Linux内核设计与实现》而写的总结,欢迎转载,请注明出处:

                                                                              http://blog.csdn.net/dlutbrucezhang/article/details/12887315


      第七章--内存管理

      Linux内核中的内存管理是比较难实现的地方,因为,它不像在用户空间中有内核给它提供内存的保护机制。它自己就是内核,它需要内存了,只有它自己去控制,没有什么系统可以为它提供保护。稍微不注意,可能就会出现问题,好一点的情况就是系统崩溃,差的情况可能就是导致数据丢失了。而且,在前面几章的叙述中,我们知道内核在做一些事的时候是不能睡眠的,这样会导致效率的急剧降低。所以,理解内核中的内存分配管理是很有必要的。

      1.页

      页是Linux内核中对内存管理中抽象的一种概念,它是虚拟地址的基础。虽然处理器对内存的处理最小单元是字或者是字节,但是,理解页的概念仍是学好内存管理的基础。首先,贴出页的结构:
struct page {
struct list_head list;
struct address_space *mapping;
unsigned long index;
struct page *next_hash;
atomic_t count;
unsigned long flags;
struct list_head lru;
unsigned long age;
wait_queue_head_t wait;
struct page **pprev_hash;
struct buffer_head * buffers;
void *virtual; 
struct zone_struct *zone;
}

      下面我对这个结构中比较重要的字段进行简单的介绍(红色字标记)。
1.1 list:指向页的链表的头
1.2 mapping:虚拟地址映射到物理地址的指针
1.3 count:页的引用计数,往往一个页不止是一个进程在使用
1.4 flags:标记页的状态,比如页是否为脏
1.5 lru:对应于lru算法,最近最少使用的页链表的头,用于内存不足时回收时使用
1.6 virtual:页的虚拟地址
1.7 zone:页属于哪个区(下文中会有介绍)
      系统中属于内存的每个页都对应着这样一个页结构用于对页的管理。

      2.区

      由于硬件的限制,内核不能够对内存中所有的页一视同仁。所以,内核把特性相似的页划分为同一个区。这里介绍主要的划分区的方法,把内存划分为三个区:
2.1 DMA :这个区中的页位于内存开始处 ,一般的划分是 0--16M,这个区中的页可以用来进行DMA操作,当然,它也可以当做是普通的页来使用
2.2 NORMAL :这个区中的页是内核占据的地方,内核一般会从这个区中分配和释放内存,它的内存范围一般是 16M--896M,是能够正常映射的页
2.3 HIGH :这个区中页就是所谓的高端内存,这个区中的页不能够直接使用,其中的页不能永久的映射到内核地址空间,它的范围是 896M--最大内存范围
      当然,这种划分方式是对于 32 位操作系统的,对于64位操作系统,内核可以访问内存的所有页,所以,不存在高端内核的说法。

      3.slab层

      分配和释放内存是内核经常做的事,正是由于这种频繁的操作,内核的设计者提出了高速缓存的概念,把经常用到的数据结构缓存起来,在使用时可以很快的分配这些结构,当用完之后并不直接释放,而是把它们再次加入到高速缓存中,等待下次用于分配。高速缓存只是一个内存区,怎样高效的管理高速缓存呢?内核设计者又提出了一个重要的概念,slab。用它来进行内存的分配和释放。
      slab是一组连续的页组成的结构,其中包含了高速缓存的对象。每个slab都处于三个状态之一。满,空,部分满。每次进行内存分配的时候,总是从部分满的slab中分配。若不存在那样的slab,那么就会从空的slab中分配,如果不存在空的,那么就需要调用内核函数请求为slab分配新的页面了。
原创粉丝点击