1 简介
物理内存就是系统硬件提供的内存大小,是真正的内存,它是计算机非常宝贵的资源,而对于计算机而言,如何高效的管理物理内存是一个更加重要的任务。在物理内存管理
技术中经常遇到的两个概念是内核空间和用户空间,如Linux下每个用户进程有 4GB长度的虚拟内存,其中 0 ~3G B是用户态空间,由各进程独占,3 ~4G B是内核态空间,由所有
进程共享,在内核态申请内存比在用户态申请内存要更为直接。
2 Linux系统的段、页机制
Linux内核管理物理内存是通过分页机制实现的,它将整个内存划分成无数4k(在i386体系结构中)大小页,从而分配和回收内存的基本单位便是内存页了。故,段、页机制是
Linux内核管理物理内存的基础。一个简单的程序执行过程为:将一段程序放入内存中,CPU“取指执行”,这样内存就被使用了。如图1所示,实际的程序是分段的,例如代码段、
数据段,所以在实际的程序执行过程中,是分段放入内存的。
图1程序执行流程
在图1中,涉及到一个内存分区的类型,一般有“固定分区”和“可变分区”,程序的每个段的大小都是不同的,所以一般选择“可变分区”。在实际执行过程中,由于不断的请求
释放,“可变分区”也造成了内部碎片的问题,如图2所示。
图2 内部碎片
通过分页机制,可以解决内部碎片问题。一个程序由多个段组成,每一个段不是直接放到内存,而是将段打散成多个页,所以每个段放在内存的多个页中。Linux内核管理物
理内存是将整个内存划分成无数个4k(在i386体系结构中)大小的页,由于每一页都比较小,所以一个进程最多浪费4K,这样内存碎片也会非常小。
图3 内存分页
分页单元把所有的RAM分成固定长度的页框(page frame)(有时叫做物理页)。每一个页框包含一个页(page),也就是说一个页框的长度与一个页的长度一致。页框
是贮存的一部分,因此也是一个存储区域,区分页和页框是很重要的。
3 物理内存管理层次
Linux把物理内存划分为3个层次来管理:存储节点(Node)、管理区(Zone)和页面(Page),并用 3 个相应的数据结构来描述:(1)页面(Page)数据结构;(2)
管理区 Zone;(3)存储节点(Node)的数据结构。
3.1存储节点(Node)
存储节点的来源与Linux 对物理内存的描述机制有关。在传统的计算机结构中,整个物理内存都是均匀一致的,CPU访问这个空间中的任何一个地址所需要的时间都相同,
所以把这种内存称为“一致存储结构(Uniform MemoryArchitecture)”,简称 UMA。可是,在一些新的系统结构中,特别是多 CPU 结构的系统中,物理存储空间在这方面的一
致性却成了问题,所以有了“非一致存储结构(Non-UniformMemoryArchitecture),简称NUMA。由于NUMA的引入,就需要存储管理机制的支持,因此,Linux内核从2.4版本
开始就提供了对NUMA的支持(作为一个编译可选项)。为了对NUMA进行描述,引入一个新的概念 —“存储节点(或叫节点)”,把访问时间相同的存储空间就叫做一个“存储节点”。
一般来说,连续的物理页面应该分配在相同的存储节点上。存储节点的数据结构为pglist_data,定义于Include/linux/mmzone.h中。若干存储节点的 pglist_data 数据结构可以通
过node_next形成一个单链表队列。每个结构中的node_mem_map 指向具体节点的page结构数组,而数组 node_zone[]就是该节点的最3个页面管理区。
3.2管理区(Zone)
Linux把物理内存的管理主要是为了解决从内核虚拟地址到物理地址的映射。IA32架构中内核虚拟地址空间只有1GB大小(从3GB到4GB),因此可以直接将1GB大小的物理
内存(即常规内存)映射到内核地址空间,但超出1GB大小的物理内存(即高端内存)就不能映射到内核空间。为了对物理页面进行有效的管理,Linux又把物理页面划分为3个
区:(1)专供DMA使用的 ZONE_DMA区(小于 16MB);(2)常规的ZONE_NORMAL区(大于16MB小于 896MB);(3)内核不能直接映射的区 ZONE_HIGME 区(大于
896MB)。物理内存被划分为3个区来管理,每个区都用structzone_struct结构来表示,对struct zone_struct 结构不赘述。
3.3页面(Page)
Linux物理内存管理以页为单位,它将整个内存划分成无数4k大小页,形成一个分页机制。内存中每个物理页面都有一个 struct page 结构,位于 include/linux/mm.h,该结
构包含了对物理页面进行管理的所有信息。
3.4相互关系
根据存储节点、管理区以及页面的基本简介和数据结构,能明显看出,它们之间的关系为如图4所示:图4 管理层次关系图
3.5页面管理机制
为了对页面管理机制作出初步准备,Linux使用了一种叫 bootmem分配器(Bootmem Allocator)的机制,这种机制仅仅用在系统引导时,它为整个物理内存建立起一个页面位图。用来存放位图的数据结构为 bootmem_data,其中有一些相关的函数:
(1)init_bootmem()函数:这个函数仅在初始化时用来建立bootmem分配器 ;
(2)free_bootmem( )函数:这个函数把给定范围的页面标记为空闲(即可用),也就是,把位图中某些位清 0,表示相应的物理内存可以投入分配;
(3)reserve_bootmem()函数:这个函数用来保留页面;
(4)__alloc_bootmem()函数:这个函数以循环轮转的方式从不同节点分配页面。
(5)free_all_bootmem()函数:这个函数用来在引导时释放页面,并清除 bootmem 分配器。
4 物理内存管理机制
基于物理内存在内核空间中的映射原理,物理内存的管理方式也有所不同。内核中物理内存的管理机制主要有伙伴算法,slab高速缓存和vmalloc机制。其中buddy伙伴算法
和slab高速缓存都在物理内存映射区分配物理内存,而vmalloc机制则在高端内存映射区分配物理内存。
(1)伙伴算法:负责大块连续物理内存的分配和释放,以页框为基本单位。该机制可以避免外部碎片。
(2)slab分配:负责小块物理内存的分配,并且它也作为高速缓存,主要针对内核中经常分配并释放的对象。
(3)vmalloc机制:使得内核通过连续的线性地址来访问非连续的物理页框,这样可以最大限度的使用高端物理内存。
网上有很多关于这个三个机制的内容,这里不赘述。
相关参考网址:
http://blog.csdn.net/u014774781/article/details/47710673##1
http://www.cnblogs.com/kkshaq/p/4526665.html