页
内核把物理页作为内存管理的基本单位。尽管处理器的最小可寻址单位通常为字(甚至字节),但是内存管理单元(MMU 管理内存并把虚拟地址转换为物理地址的硬件)通常以页为单位进行处理。正是因为如此,MMU以页(page)大小为单位来管理系统中的页表。从虚拟内存的角度来看,页就是最小单位。
struct page{
unsigned long flags;
atomic_t _count;
atomic_t _mapcount;
unsigned long private;
struct address_space *mapping;
pgoff_t index;
struct list_head lru;
void *virtual;
};
- flag域用来存放页的状态,这些状态包括页是不是脏的,是不是被锁定在内存中等。
- _count域存放页的引用计数,当计数器值变为-1时,就说明当前内核并没有引用这一页,在新的分配中就可以使用它。
- virtual域是页的虚拟地址。在高端内存并不永久映射到内核地址空间上,这时域的值为null,需要的时候动态映射这些页。
内核用这一个结构来管理系统中所有的页,因为内核需要知道一个页是否空闲。如果已经分配,内核还需要知道谁拥有这个页。拥有者可能是用户空间进程、动态分配的内核数据、静态内核代码或页高速缓存等。
计算页管理内存开销,假设struct page占40字节,假定系统物理页为8kb大小,系统有4GB物理内存,那么系统中一共有524288个页,page结构体要消耗20MB,这个体量相对于4GB而言只占很小一部分。
区
由于硬件的限制,内核并不能对所有页一视同仁。有些页位于内存中特定的物理地址上,所以不能将其用于一些特定的任务。由于存在了这种限制,所以内核把页划分为不同的区(zone)。内核使用区对具有相似特征的页进行分组。
Linux必须处理如下两种由于硬件存在缺陷而引起的内存寻址问题:
- 一些硬件只能用某些特定的内存地址来执行DMA(直接访问内存)
- 一些体系结构的内存的物理寻址访问比虚拟寻址范围大的多,这样就有一些内存永远不能映射到内核空间上。
因为这些限制条件,Linux主要使用了四种区:
- ZONE_DMA -- 这个区包含的页功能来执行DMA操作
- ZONE_DMA32 -- 和ZONE_DMA类似,该区包含的页面可用来执行DMA操作,而和ZONE_DMA不同之处在于,这些页面只能被32位设备访问。
- ZONE_NORMAL 这个区浩航的都是能正常映射的页。
- ZONE_HIGHEM 这个区包含“高端内存”,其中的页并不能永久地映射到内核地址空间。
Linux把系统的页划分为区,形成不同的内存池,不是所有的体系机构都定义了全部的四个区,有些64位的体系结构,如Intel的x86-64体系机构可以映射和处理64位的内存空间,所以x86-64没有ZONE_HIGHMEM区,所有的物理内存都处于ZONE_DMA和ZONE_NORMAL区。
slab层
分配和释放数据结构是所有内核中最普遍的操作之一。为了便于数据的频繁分配和回收,编程人员常常会用到空闲链表。空闲链表包含可供使用的、已经分配好的数据结构块。当代码需要一个新的数据结构实例是,就可以从空闲链表中抓取一个,而不需要分配内存,再把数据放进去,以后当不需要这个数据结构的实例,就把它放回空闲链表,而不是释放它。从这个角度讲,空闲链表相当于对象的高速缓存。
内核中,空闲链表面临的主要问题之一是不能全局控制。当可用内存变得紧缺时,内核无法通知每个空闲链表,让其收缩缓存的大小以便释放出一些内存来。实际上,内核根本就不知道存在任何空闲链表。为了弥补这一缺陷,也为了使代码更加稳固,Linux内核提供了slab层(也就是slab分配器)。slab分配器扮演了通用数据结构缓存层的角色。
slab分配器试图在几个基本原则之间寻求一种平衡:
- 频繁使用的数据结构也会频繁分配和释放,因此应当缓存他们。
- 频繁分配和回收必然导致内存碎片,因为已释放的数据结构又会放回空闲链表,因此不会导致碎片。
- 回收的对象可以立即投入下一次分配,因此,对于频繁释放和分配,空闲链表能提高性能。
- 如果分配器知道对象大小,页大小和总的高速缓存的大小这样的概念,它会做出更明智的决策。
- 如果让部分缓存专属于单个处理器,那么分配和释放就可以在不加SMP锁的情况下进行。
- 如果分配器是与NUMA相关的,它就可以从相同的内存节点为请求者进行分配。
- 对存放的独享进行着色(color),以防止多个对象映射到相同的高速缓存行(cache line)。
slab层把不同的对象划分为所谓的高速缓存组。其中每个高速缓存组存放不同类型的对象,每种对象类型对应一个高速缓存。slab由一个或多个物理上连续的页组成。一般情况下,slab也就仅仅由一页组成。每个高速缓存可以由多个slab组成。每个slab有三种状态:满、部分、空闲。
相关推荐
天大 操作系统 课程 linux 内存管理 实验报告
linux内存管理 linux内存管理 linux内存管理
linux内存管理源代码导读 pdf格式
linux 内存管理学习总结 学习心得 内存管理纲要
linux内存管理工具
个人多年学习并总结的有关Linux内存管理的笔记,希望对Linux内核爱好者有所帮助!
Linux内存管理编程技术.doc
我不可能完全理解LINUX内存管理的精髓,肯定有很多地方理解错误。希望大 家能够指正,以便提高,谢谢。 学习方法: 可能您第一次阅读的时候很多地方都不理解,不用担心。那您可能需要阅读一些 文件系统的知识。 或者...
整个内存管理系统可以分为2部分来看待: 第一部分是对物理内存的管理, 第二部分是对虚拟内存的管理. 物理内存管理的对象是板载的物理内存(DDRAM), 它把物理内存按页划分, 并把这些页放到一个池子里面. 物理内存管理...
Linux内存管理实验.pdf
一种Linux内存管理机制.pdf
Linux内存管理ppt讲义,希望对你的工作学习有所帮助。
《深入理解LINUX内存管理》学习笔记c.PDF
详细介绍linux内核内存管理,从内核思想详细介绍伙伴算法、slab内存管理
《深入理解LINUX内存管理》学习笔记b.PDF
Linux内存管理 vs. Windows 2000内存管理
很清晰的描述了linux内存虚拟及物理内存的划分,包括: node介绍 zone介绍 3G~4G内核空间布局 内核整体mm管理结构
与内存管理系统相关的各种flags汇总如下: 每个物理page有自己的flags, 定义在struct page -> unsigned long flags; 详情见2.2.2节的《page》 每个内存块(多个page组成一个内存块)有自己的pageblock_flags, ...
介绍Linux的内存管理系统,例如虚拟地址空间及地址映射。
linux内存管理(重要)