您的位置 首页 被动

linux下内存办理学习心得(一)

最近在学习内存管理的时候,发现对linux下的所谓内存如何管理如何分配都不熟悉,通过最近的查阅资料可总结如下,如有不妥之处欢迎大家批评

最近在学习内存办理的时分,发现对linux下的所谓内存怎么办理怎么分配都不了解,经过最近的查阅材料可总结如下,如有不当之处欢迎咱们批判与纠正。

总的的来说linux的内存办理其实首要难了解的是以下几个部分:

1、虚拟地址、物理地址、线性地址、逻辑地址之间的差异。

2、用户地址空间与内核地址空间差异。

3、内核怎么分配所谓的地址。

4、一个可履行程序的地址散布以及运转地址分配。

现在我也大约总结这几个,其实这方面的常识必定许多,但限于才能只能怎么,也尽最大努力详细分析其间原委。注:许多是参阅了网上的大牛总结的。

一、各地址之间差异

1、虚拟地址

其间各种地址的概念咱们都可查阅到,我也就不多说了,虚拟地址便是为了给用户一个更大的运用空间(当然这个运用空间必定是虚拟了的),然后32位下面用户地址空间也便是虚拟地址空间规模便是0–4GB。其间这个规模又能够划为0–3GB-1用户空间和3GB–4GB-1的内核空间。其间进程都各自有各自的0–3GB-1地址规模而同享3GB–4GB-1的内核空间。更详细的请往下此处不讲为了咱们先有个微观的知道。

1、分页单元中,页目录的地址放在CUP的CR3寄存器中,是进行抵抗转化的开端点。

2、每个进程,都有其独立的虚拟地址空间,运转一个进程,首要需求将它的页目录地址放在CR3寄存器中,其他的进程的保存下来。

3、每一个32位的线性地址被划分为三部分:页目录索引(10位):页表索引(10位):偏移12位。

装换:

1、先装入进程的页目录地址(调度程序把这个地址装入CR3中);

2、根据线性地址前10位,在页目录中找到对应的索引项,页目录中的项是一个页表的地址;

3、根据线性地址的中心10位,在页表中找到页的开端地址;

4、将页的开端地址与线性地址的最终12为偏移地址相加最终为物理地址。

二、用户地址与内核地址

Linux 操作系统和驱动程序运转在内核空间,应用程序运转在用户空间,两者不能简略地运用指针传递数据,由于Linux运用的虚拟内存机制,用户空间的数据或许被换出,当内核空间运用用户空间指针时,对应的数据或许不在内存中。

其间内核地址空间是由内核担任映射,它并不会跟着进程改动,是固定的。其间内核空间散布如下:

(1)直接内存映射区

从3G开端,最大896M的线性地址区间,咱们称作直接内存映射区,这是由于该区域的线性地址和物理地址之间存在线性装换联系:线性地址=3G+物理地址

(2)动态内存映射区

又内核函数vmalloc来进行分配,其特点是线性空间接连,但物理地址空间不用定接连。

(3)永久内存映射区

运用kmap函数将分配到得896M以上的高端内存映射到该区

(4)固定映射区

特别用处

用户空间

用户空间是0-3GB-1的空间规模。这儿就提早说一下程序镜像加载到运转的进程。

首要二进制程序是放在外部存储器中的,当发动一个进程的时分先分配自己进程的虚拟空间,这个时分将程序镜像加载到内存(详细内核进程下面介绍),怎么镜像很大的话先加载一部分(这部分是多大?我还不清楚有待研讨),然后这个时分进程的空间就会映射(必定留意是映射,由于根本就没有这样的地址,这仅仅个虚的),此刻该进程如同有了这个镜像了,那么进程履行的时分根据线性地址找到物理地址(内存)中的代码履行。便是这么简略。

三、内核分配内存

在linux操作系统中,每个进程都经过一个task_struct的结构体描叙,每个进程的地址空间都经过一个mm_struct描叙,c语言中的每个段空间都经过vm_area_struct表明,他们联系如下 :

  当运转一个程序时,操作系统需求创立一个进程,这个进程和程序之间都干了些什么呢?

  当一个程序被履行时,该程序的内容有必要被放到进程的虚拟地址空间,关于可履行程序的同享库也是如此。可履行程序并非真实读到物理内存中,而仅仅链接到进程的虚拟内存中。

  当一个可履行程序映射到进程虚拟地址空间时,一组vm_area_struct数据结构将被产生。每个vm_area_struct数据结构表明可履行形象的一部分;是可履行代码,或是初始化的数据,以及未初始化的数据等。

  linux操作系统是经过sys_exec对可履行文件进行映射以及读取的,有如下几步:

  1.创立一组vm_area_struct

  2.圈定一个虚拟用户空间,将其开端完毕地址(elf段中已设置好)保存到vm_start和vm_end中。

  3.将磁盘file句柄保存在vm_file中

  4.将对应段在磁盘file中的偏移值(elf段中已设置好)保存在vm_pgoff中;

  5.将操作该磁盘file的磁盘操作函数保存在vm_ops中

  留意:这儿没有对应 的页目录表项创立页表,更不存在设置页表项了。

  假定现在程序中有一条指令需求读取上面vm_start–vm_end之间的某内容

  例如:mov [0x08000011],%eax,那么将会履行如下序列:

  1.cpu根据CR3(current->pgd)找到0x08000011地址对应的pgd[i],由于该pgd[i]内容坚持为初始化状况即为0,导致cpu反常.

  2.do_page_fault被调用,在该函数中,为pgd[i]在内存中分配一个页表,并让该表项指向它,如下图所示:

  留意:这儿i为0x08000011高10位,j为其间间10位,此刻pt表项悉数为0(pte[j]也为0);

  3.为pte[j]分配一个真实的物理内存页面,根据vm_area_struct中的vm_file、vm_pgoff和vm_ops,调用filemap_nopage将磁盘file中vm_pgoff偏移处的内容读入到该物理页面中,如下图所示:

  ①。分配物理内存页面;

  ②。从磁盘文件中将内容读取到物理内存页面中

  从上面咱们能够知道,在进程创立的进程中,程序内容被映射到进程的虚拟内存空间,为了让一个很大的程序在有限的物理内存空间运转,咱们能够把这个程序的开端部分先加载到物理内存空间运转,由于操作系统处理的是进程的虚拟地址,假如在进行虚拟到物理地址的转化工程中,发现物理地址不存在时,这个时分就会产生缺页反常(nopage),接着操作系统就会把磁盘上还没有加载到内存中的数据加载到物理内存中,对应的进程页表进行更新。或许你会问,假如此刻物理内存满了,操作系统将怎么处理?

  下面咱们看看linux操作系统是怎么处理的:

  假如一个进程想将一个虚拟页装入物理内存,而又没有可运用的闲暇物理页,操作系统就有必要筛选物理内存中的其他页来为此页腾出空间。

  在linux操作系统中,物理页的描叙如下:

  struct mem_map

  {

  1.本页运用计数,当该页被许多进程同享时计数将大于1.

  2.age描叙本页的年纪,用来判别该页是否为筛选或交流的好候选

  3.map_nr描叙物理页的页帧号

  }

  假如从物理内存中被筛选的页来自于一个映像或数据文件,而且还没有被写过,则该页不用保存,它能够丢掉。假如有进程在需求该页时就能够把它从映像或数据文件中取回内存。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/beidong/261387.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部