Linux是如何管理内存的

物理内存的管理  

  Linux管理物理内存是使用分页机制实现的。为了使分页机制在32位和64位体系结构下高效工作,Linux采用了一个四级分页策略

  Linux支持多种内存分配机制。分配物理内存页框的主要机制是页面分配器,它使用了著名的伙伴算法作为物理内存分配机制。

  管理一块内存的基本思想如下。刚开始,内存由一块连续的片段组成,下图的简单例子是64个页面。当一个内存请求到达时,首先向上舍入到2的幂,比如8个页面。然后整个内存被分割成两半,如图b所示。因为这些片段还是太大了,较低的片段被再次二分(c),然后再二分(d)。现在我们有一块大小合适的内存,因此把它分配给请求者,如图d所示。

  

  现在假定8个页面的第二个请求到达了。这个请求有(e)直接满足了。此时4个页面的第三个请求到达了。最小可用的块被分割(f),然后其一半被分配(g)。接下来,8页面里的第二个块碑释放(h)。最后,8页面的另一个块也被释放。因为刚刚释放的两个邻接的8页面块来自同一个16页面块,它们合并起来得到一个16页面的块(i)。

虚拟地址空间 

  Linux为每个进程维持一个单独的虚拟地址空间。如下图所示。

  

  

  虚拟地址空间被分割成同构连续页面对齐的区域。也就是说,每个区域由一系列连续的具有相同保护和分页属性的页面组成。代码段、数据段、堆、共享库段以及用户栈都是不同的区域。每个存在的虚拟页面都保存在某个区域中,而不属于某个区域的虚拟也是不存在的。在虚拟地址空间的区之间可以有空隙。所有对这些空隙的引用都会导致一个严重的页面故障。

  在内核中,每个区是用vm_area_struct项来描述的。一个进程的所有vm_area_struct用一个链表连接在一起,并且按照虚拟地址排序以便可以找到所有的页面。当这个链表太长时(多于32项),就创建一个树来加速搜索。vm_area_struct项列出了该区的属性。这些属性包括:保护模式(如,只读或者可读可写),是否固定在内存中(不可换出)、朝向哪个方向生长(数据段向上,栈段向下)。

  vm_area_struct也记录了该区是私有的还是跟一个或多个其他进程共享的。fork之后,Linux为子进程复制一份区链表,但是为了让父子进程指向相同的也表。区标记为可读可写,但是页面却被标记为只读。如果任何一个进程试图写页面,就会产生一个保护故障,此时内核发现该内存区域逻辑上是可写的,但是页面却不是,因此它把该页面的一个副本给当前进程同时标记为可读可写。这个机制就说明了写时复制是如何实现的。

  vm_area_struct也记录了该区是否在磁盘上有备份存储,如果有,在什么地方。代码段把可执行二进制文件作为备份存储,内存映射文件把磁盘文件作为备份存储。其他区,如栈,直到它们不得不被换出,否则没有备份存储被分配。

  一个顶层内存描述符mm_struct收集属于一个地址空间的所有虚拟内存区相关的信息,还有关于不同段(代码、数据、栈)和用户共享地址空间的信息等。一个地址空间的所有vm_area_struct元素可以通过内存描述符用两种方式访问。首先,它们是按照虚拟地址顺序组织在链表中的。这种方式的有用之处是:当所有的虚拟地址区需要被访问时,或者当内核查找分配一个指定大小的虚拟内存区域时。此外,vm_area_struct项目被组织成二叉“红黑”树。这种方法用于访问一个指定的虚拟内存地址。为了能够用这两种方法访问进程地址空间的元素,Linux为每个进程使用了更多的状态,但是却允许不同的内核操作来使用这些访问状态,这对进程而言更加高效。

  下图强调了记录一个进程中虚拟存储器区域的内核数据结构。内核为系统中的每个进程维护一个单独的任务结构(源代码中的task_struct)。任务结构中的元素包含或者指向内核运行该进程所需要的所有信息(例如,PID,指向用户栈的指针、可执行目标文件的名字以及程序计数器)。

  

  task_struct中的一个条目指向mm_struct,它描述了虚拟存储器的当前状态。我们感兴趣的两个字段是pdg和mmap,其中pdf指向第一级页表(页全局目录)的基址,而mmap指向一个vm_area_struct(区域结构链表),其中每个vm_area_strcuts都描述了当前虚拟地址空间的一个区域(area)。当内核运行这个进程时,它就将pdf存放在CR3控制寄存器中。

  为了我们的目的,一个具体区域的区域结构包含下面的字段:

  vm_struct:指向这个区域的起始处。

  vm_end: 指向这个区域的结束处。

  vm_prot: 描述这个区域内包含的所有页的读写许可权限。

  vm_flags:描述这个区域内的页面是与其他进程共享的,还是这个进程私有的、

  vm_next: 指向链表中下一个区域结构。

虚拟地中空间到物理地址空间的映射

  虚拟存储的实现需要依靠硬件的支持,对于不同的CPU来说是不同的。但是几乎所有的硬件都采用一个MMU((Memmory Management Unit)的部件来进行映射,如下图所示。

  

  在页映射模式下,CPU发出的是Virtual Address, 即我们的程序看到的是虚拟地址。经过MMU转换以后就变成了Physical Address。一般MMU都集成在CPU内部了,不会以独立的部件存在。

时间: 2024-10-09 21:59:08

Linux是如何管理内存的的相关文章

linux内核分析之内存管理

1.struct page 1 /* Each physical page in the system has a struct page associated with 2 * it to keep track of whatever it is we are using the page for at the 3 * moment. Note that we have no way to track which tasks are using 4 * a page, though if it

Linux系统基本的内存管理知识讲解

内存是Linux内核所管理的最重要的资源之一.内存管理系统是操作系统中最为重要的部分,因为系统的物理内存总是少于系统所需要的内存数量.虚拟内存就是为了克服这个矛盾而采用的策略.系统的虚拟内存通过在各个进程之间共享内存而使系统看起来有多于实际内存的内存容量.Linux支持虚拟内存, 就是使用磁盘作为RAM的扩展,使可用内存相应地有效扩大.核心把当前不用的内存块存到硬盘,腾出内存给其他目的.当原来的内容又要使用时,再读回内存. 一.内存使用情况监测 (1)实时监控内存使用情况 在命令行使用“Free

linux内核--段页式管理内存的方法

一.概念 物理地址(physical address) 用于内存芯片级的单元寻址,与处理器和CPU连接的地址总线相对应. --这个概念应该是这几个概念中最好理解的一个,但是值得一提的是,虽然可以直接把物理地址理解成插在机器上那根内存本身,把内存看成一 个从0字节一直到最大空量逐字节的编号的大数组,然后把这个数组叫做物理地址,但是事实上,这只是一个硬件提供给软件的抽像,内存的寻址 方式并不是这样.所以,说它是"与地址总线相对应",是更贴切一些,不过抛开对物理内存寻址方式的考虑,直接把物理

<Linux内核源码>内存管理模型

题外语:本人对linux内核的了解尚浅,如果有差池欢迎指正,也欢迎提问交流! 首先要理解一下每一个进程是如何维护自己独立的寻址空间的,我的电脑里呢是8G内存空间.了解过的朋友应该都知道这是虚拟内存技术解决的这个问题,然而再linux中具体是怎样的模型解决的操作系统的这个设计需求的呢,让我们从linux源码的片段开始看吧!(以下内核源码均来自fedora21 64位系统的fc-3.19.3版本内核) <include/linux/mm_type.h>中对于物理页面的定义struct page,也

Linux内核工程导论——内存管理(一)

Linux内存管理 概要 物理地址管理 很多小型操作系统,例如eCos,vxworks等嵌入式系统,程序中所采用的地址就是实际的物理地址.这里所说的物理地址是CPU所能见到的地址,至于这个地址如何映射到CPU的物理空间的,映射到哪里的,这取决于CPU的种类(例如mips或arm),一般是由硬件完成的.对于软件来说,启动时CPU就能看到一片物理地址.但是一般比嵌入式大一点的系统,刚启动时看到的已经映射到CPU空间的地址并不是全部的可用地址,需要用软件去想办法映射可用的物理存储资源到CPU地址空间.

[转载]linux段页式内存管理技术

原始博客地址: http://blog.csdn.net/qq_26626709/article/details/52742470 一.概述 1.虚拟地址空间 内存是通过指针寻址的,因而CPU的字长决定了CPU所能管理的地址空间的大小,该地址空间就被称为虚拟地址空间,因此32位CPU的虚拟地址空间大小为4G,这和实际的物理内存数量无关.Linux内核将虚拟地址空间分成了两部分: 一部分是用户进程可用的,这部分地址是地址空间的低地址部分,从0到TASK_SIZE,称为用户空间 一部分是由内核保留使

Linux之进程管理及Shell脚本

使用!来调用过往命令 !! 重复执行上一条指令 !a 重复执行上一条以a为首的指令 !nubmer 重复执行上一条在history表中记录号码为number的指令 !-number重复执行前第number条指令 ailas abc='cd xxxxxxxxxxx/xxxxxxxx/xxxxxxxxxxxxx' unalias abc " "将一串字符当成字符串来看,可以转译特殊字符 ' '将一串字符当成字符串来看,无法转译特殊字符 ·能够返回命令执行的结果 echo `uname -a

Linux进程上下文切换过程context_switch详解--Linux进程的管理与调度(二十一)【转】

转自:http://blog.csdn.net/gatieme/article/details/51872659 版权声明:本文为博主原创文章 && 转载请著名出处 @ http://blog.csdn.net/gatieme 目录(?)[-] 前景回顾 1 Linux的调度器组成 2 调度工作 进程上下文 1 进程上下文的概念 2 上下文切换 context_switch进程上下文切换 1 context_switch完全注释 2 prepare_arch_switch切换前的准备工作

Linux吃掉我的内存

在Windows下资源管理器查看内存使用的情况,如果使用率达到80%以上,再运行大程序就能感觉到系统不流畅了,因为在内存紧缺的情况下使用交换分区,频繁地从磁盘上换入换出页会极大地影响系统的性能.而当我们使用free命令查看Linux系统内存使用情况时,会发现内存使用一直处于较高的水平,即使此时系统并没有运行多少软件.这正是Windows和Linux在内存管理上的区别,乍一看,Linux系统吃掉我们的内存(Linux ate my ram),但其实这也正是其内存管理的特点. Linux吃掉我的内存