linux内核之内存管理.docVIP

  1. 1、本文档共8页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多

Linux内核之内存管理

作者:harveywang

邮箱:harvey.perfect@

新浪博客地址:/harveyperfect,有关于减肥和学习英语相关的博文,欢迎交流

把linux内存管理分为下面四个层面

(一)硬件辅助的虚实地址转换

(二)内核管理的内存相关

(三)单个进程的内存管理

(四)malloc软件

处理器硬件辅助的虚实地址转换(以x86为例)

在x86中虚实地址转换分为段式转换和页转换。段转换过程是由逻辑地址(或称为虚拟地址)转换为线性地址;页转换过程则是将线性地址转换为物理地址。段转换示意图如下

X86支持两种段,gdt和ldt(全局描述段表和局部描述符段表),在linux中只使用了4个全局描述符表,内核空间和用户空间分别两个gdt,分别对应各自的代码段和数据段。也可以认为在linux中变相地disable了x86的段式转换功能。

页转换示意图如下

在linux中x86的cr3寄存器(页表基地址寄存器)保存在进程的上下文中,在进程切换时会保存或回复该寄存器的内容,这样每个进程都有自己的转换页表,从而保证了每个进程有自己的虚拟空间。

内核管理的内存相关

从几个概念展开内存管理:node、zone、buddy、slab

1、Node

SGIAltix3000系统的两个结点

如上图,NUMA系统的结点通常是由一组CPU(如,SGIAltix3000是2个Itanium2CPU)和本地内存组成。由于每个结点都有自己的本地内存,因此全系统的内存在物理上是分布的,每个结点访问本地内存和访问其它结点的远地内存的延迟是不同的,为了优化对NUMA系统的支持,引进了Node来将NUMA物理内存进行划分为不同的Node。而操作系统也必须能感知硬件的拓扑结构,优化系统的访存。

但是Intelx86系统不是NUMA系统。为了保持代码的一致性,在x86平台上,Linux将所有物理内存都划分到同一个Node。事实上,对于非NUMA体系结构,也是如此处理的。

Linux系统用定义了数组pg_data_tnode_data[MAX_NUMNODES]来管理各个node。

2、Zone

Linux中Node、Zone和页的关系

每个结点的内存被分为多个块,称为zones,它表示内存中一段区域。一个zone用structzone结构描述,zone的类型主要有ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。ZONE_DMA位于低端的内存空间,用于某些旧的ISA设备。ZONE_NORMAL的内存直接映射到Linux内核线性地址空间的高端部分,ZONE_HIGHMEM位于物理地址高于896MB的区域。例如,在X86中,zone的物理地址如下:

内核空间只有1GB线性地址,如果使用大于1GB的物理内存就没法直接映射到内核线性空间了。当系统中的内存大于896MB时,把内核线性空间分为两部分,内核中低于896MB线性地址空间直接映射到低896MB的物理地址空间;高于896MB的128MB内核线性空间用于动态映射ZONE_HIGHMEM内存区域(即物理地址高于896MB的物理空间)。

3、Buddy

如上图所示,每个zone区域都采用伙伴系统(buddysystem)来管理空闲内存页面。把所有的空闲页框分组为11个块链表,每个块链表分别包含大小为1,2,4,8,16,32,64,128,256,512和1024个连续的页框。链表编号分别为0,1,2,3,…k…10。

从buddysystem中申请页面过程:

根据申请存储区域大小查找对应的编号为K的块链表。

如果编号K的链表为空,则向编号为k+1的链表申请一个存储区域。如果编号为k+1链表不为空,系统从编号为k+1的链表上拆下一个区域,并将拆下的区域分为两个2^k的区域,一个返还给申请者,另一个则挂到编号为k的链表。

如果编号为k+1的链表也为空,编号为k+2的链表不为空。则从k+2的链表中拆下一个区域变为两个2^(k+1)区域,一个挂到编号为k+1的链表上,把另一个拆为两个2^k的区域,一个返还给申请者,把另一个挂到编号为k的链表上。

如果k+2的链表也为空,则一直向上迭代,直到编号为10的链表为止,如果编号为10的链表还为空,则申请失败。

向buddysystem中释放页面过程:

在向buddysystem释放页面时,总会检测释放的页面和链表中其他页面是否可以组成一个更大一级的页面,如果可以组成,则把这两个区域组成一个并挂到更高一级的链表中。这个过程是迭代的,释放过程会一层层向上找伙伴,然后合并成更大的,再向上找伙伴,实在找不到了就停止了!

疑问:按照上面的说法,是否会出现这种情况,在释放某个页面导致所有页面都组成了

文档评论(0)

187****8802 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档