2017-04-07

脱离物理内存的管理,今天咱们来聊聊进程虚拟内存的管理。因为进程直接分配和使用的都是虚拟内存,而物理内存则是有系统“按需”分配给进程,在进程看来,只知道虚拟内存的存在!


 前言:

  关于虚拟内存和物理内存这些东东,本篇不作介绍,此等基础知识参考最普通的操作系统参考书籍即可。当然有问题也可留言,我们共同学习,共同进步!

进程虚拟地址空间:

  每个进程拥有一个独立的虚拟地址空间,独立怎么体现?进程A有个地址1000,进程B也有个地址1000,为何两个地址不发生矛盾,还能正常工作,这就是独立性的体现。原来,两个相同的虚拟地址会经过自己所属进程的页表,转化成不同的物理地址。只要实际的物理地址不发生冲突,就没有关系。这一切怎么实现的呢?自然需要内核去维护。内核为每个进程维护一套页表,页表实现虚拟地址到物理地址的转换,其基地址存储在CR3寄存器中,是物理地址。x86架构下,地址线是32根,那么就可以寻址到2^32个地址,因为默认都是按字节寻址,所以虚拟地址空间就为2^32字节即4GB,64位额CPU使用48根地址线,虚拟地址空间更大。本文不做虚拟地址空间深入分析,旨在介绍虚拟地址空间是怎么使用的。

虚拟地址空间的划分:

每个进程都有自己的虚拟地址空间,但是也不能随意使用,还是需要规划好的,毕竟内存时比较稀缺的资源,咱们必须本着可持续发展的战略去使用。很明显,进程运行过程中需要的信息都要装入内存,那么进程运行期间都需要哪些信息呢?

  • 程序运行代码的二进制代码。
  • 程序使用的动态库的代码。
  • 存储全局变量和动态产生数据的堆。
  • 保存局部变量和实现函数过程调用的栈。
  • 环境换量和命令行参数的段。
  • 将文件内容映射到虚拟地址空间的的内存映射。

进程虚拟地址空间映射结构如下两种结构,在地址空间不富裕的情况下,前者比较合适。

进程的3GB空间安排大致如图所示,最底下是映射的可执行文件的映像,一般包含代码段和数据段。数据段中包含有全局变量和静态数据的空间。再往上就是堆空间,这里堆空间和MMAP区域是相对生长的,从而充分利用这些地址空间。MMAP区域上边是栈空间,而栈空间上面不使用了,所以栈一般位于进程地址空间的顶部。一般情况下栈的最高地址是用户空间可用的最高地址,当指定栈随机化时,会空闲一个随机大小,这样可在一定程度上,对栈实施保护。

每个进程结构有一个mm_struct结构管理该进程的地址空间,每个分配的内存块由一个vm_area_struct结构表示,所有的vm_area_struct结构构成一个红黑树,树根保存在mm_struct中的mm_rb字段。这点和windows的进程地址空间管理十分类似,windows下采用的是VAD树,也是个二叉树。在vm_area_struct结构中记录该内存块的起始和结束地址,同一个进程的所有vm_area_struct结构还会连接成一个链表,开始于mm_struct 中的mmap。总体来讲进程地址空间的分配主要涉及三部分:进程可执行文件的映射、堆栈的分配、MMAP区域的分配。

进程可执行文件的映射

可执行文件映射在图中的text段,这里text段包含代码、数据。代码自然是程序自身的代码,而数据就是一些常量,全局数据区,静态数据区等。具体映射方式需要根据ELF文件的格式,所以映射的细节我们不做详细介绍。当可执行文件的映像映射到进程的虚拟地址空间时,产生一组vm_area_struct结构,相当于还没执行之前,可执行文件已经被划分成了虚拟页面,由vm_area_struct管理。待程序执行时会根据vm_area_struct结构和物理内存建立映射并填充页表项,具体参见pagefault处理流程。

堆栈的分配

堆栈在程序运行时动态分配,二者的用途不同。堆主要用于动态内存的分配,可分配比较大的内存块,且必须主动申请分配,使用完后需要手动释放如malloc、new(malloc在分配更大的内存会在MMAP区域)。而栈有程序自动分配,有系统负责回收,且栈的大小一般受限,常分配比较小的内存块。

MMAP区域

MMAP 区域位于堆和栈之间,用于映射文件内容到进程虚拟地址空间。注意这里是虚拟地址空间而不是物理地址空间。 每个文件在内核对应一个inode节点,inode节点的 i_mapping字段是address_space类型,记录当前文件到进程地址空间的映射情况。address_space结构中关联了映射的内存区域vm_area_struct,私有和共享映射通过红黑树管理,而非线性映射通过链表管理。进程每打开一个文件,内核会使用一个file结构记录本次打开的情况,file结构通过f_mapping字段指向文件对应的address_space,这样进程和文件的联系就建立起来了。具体联系如下

我们提到的映射都是映射的是文件到进程虚拟地址空间,不牵涉物理地址。具体物理地址的映射由内存管理单元负责,当进程对文件发起读写操作时,最终会根据文件描述符定位到其address_space,根据address_space得到要读写的页,此时页具备虚拟地址,通过对虚拟地址进行读写发生pagefault,此时当前进程就被迫陷入到内核异常处理流程,pagefault处理流程就把本次需要的页调入内存,然后返回到用户空间继续刚才进程的运行,这里其实进程本身并感知不到缺页,它仅仅负责从文件读,具体缺页由CPU感知且处理。关于MMAP其实设计的东西很多,这里不再深入介绍,回头重开一篇文章单独讲述MMAP机制。

参考资料:LInux内核3.10.1源码、深入LInux内核架构

LInux进程虚拟地址空间的管理的更多相关文章

  1. Linux进程虚拟地址空间管理2

    2017-04-12 前篇文章对Linux进程地址空间的布局以及各个部分的功能做了简要介绍,本文主要对各个部分的具体使用做下简要分析,主要涉及三个方面:1.MMAP文件的映射过程 2.用户 内存的动态 ...

  2. linux进程虚拟地址空间

    转载源 在多任务操作系统中,每个进程都运行在属于自己的内存沙盘中.这个沙盘就是虚拟地址空间(Virtual Address Space),在32位模式下它是一个4GB的内存地址块.在Linux系统中, ...

  3. linux进程的地址空间,核心栈,用户栈,内核线程

    linux进程的地址空间,核心栈,用户栈,内核线程 地址空间: 32位linux系统上,进程的地址空间为4G,包括1G的内核地址空间,和3G的用户地址空间. 内核栈: 进程控制块task_struct ...

  4. linux进程的介绍和管理

    概述 -   在linux 中,每个执行的程序都称为一个进程,每一个进程都分配一个ID号 -   每一个进程,都会对应一个父进程,而这个父进程可以复制多个子进程,例如www服务器 -   每个进程都可 ...

  5. Linux进程地址管理之mm_struct

    FROM : http://www.cnblogs.com/Rofael/archive/2013/04/13/3019153.html Linux对于内存的管理涉及到非常多的方面,这篇文章首先从对进 ...

  6. Linux 基础 —— Linux 进程的管理与监控

    这篇文章主要讲 Linux 中进程的概念和进程的管理工具.原文:http://liaoph.com/inux-process-management/ 进程的概念 什么是进程 进程(Process)是计 ...

  7. linux进程地址空间--vma的基本操作【转】

    转自:http://blog.csdn.net/vanbreaker/article/details/7855007 版权声明:本文为博主原创文章,未经博主允许不得转载. 在32位的系统上,线性地址空 ...

  8. linux 进程地址空间的一步步探究

    我们知道,在32位机器上linux操作系统中的进程的地址空间大小是4G,其中0-3G是用户空间,3G-4G是内核空间.其实,这个4G的地址空间是不存在的,也就是我们所说的虚拟内存空间. 那虚拟内存空间 ...

  9. Linux了解进程的地址空间

    供Linux了解虚拟内存,非常好的引导了.原文链接:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=26683523&i ...

随机推荐

  1. 纯CSS炫酷3D旋转立方体进度条特效

    在网站制作中,提高用户体验度是一项非常重要的任务.一个创意设计不但能吸引用户的眼球,还能大大的提高用户的体验.在这篇文章中,我们将大胆的将前面所学的3D立方体和进度条结合起来,制作一款纯CSS3的3D ...

  2. mysql数据库批量操作

    批量KILL会话: 1.首先,根据条件将查询到要kill的进程写入文件:如:desc information_schema.processlist; SELECT concat('KILL ',id, ...

  3. 2018-11-21 ko.pureComputed的使用

    以前一直在想,ko.pureComputed 好像用不上.看起来高大上. 今天在修复一个bug时,发现了它的妙处. 在修改商品列表的页面,弹出一个新增商品的页面.关闭之后,怎么通知修改商品列表的页面发 ...

  4. CSS实现文字半透明显示在图片上方法

    CSS实现文字半透明显示在图片上方法 在css中文字半透明我们会需要使用滤镜效果也就是css中的filter:alpha来实现了,下面来看两个文字显示在图片上并且半透明的例子. CSS让一行文字显示在 ...

  5. SQL on Hadoop 的真相(1)

    转自:http://blog.jobbole.com/86710/ 这是一组系列博文,目的是详尽介绍 SQL-on-Hadoop .本系列的第一篇会介绍 Hadoop 系统的存储引擎和在线事务处理(简 ...

  6. qtcreator 中文乱码

    qt输入法不能用,ui中不能显示中文,开发板不能显示中文,这几个一直困扰这我,网上查找资料,在代码中添加各种支持,都没有解决问题.今天刚好解决了,记录于此. 参考链接 http://blog.163. ...

  7. Modify the server ports

    在eclipse中配置好tomcat后,如今有需求须要在一个eclipse启动两个tomcat甚至很多其它,仅仅改动tomcat的8080port肯定不行的,详细须要改动tomcat的shutdown ...

  8. 学习:erlang正则

    一.re:run/3. ①.re:run("321321","2132",[caseless]).     {match,[{1,4}]} %% 返回值是 匹配 ...

  9. 多个return和一个return

    //一个returnnamespace CleanCSharp.Methods.Dirty { class MethodExitPoints { public string GenerateAgeAp ...

  10. 用原生Canvas写贪吃蛇及问题解决

    为了学习Canvas,写了这个小游戏贪吃蛇供自己和大家学习 Github: https://github.com/zhiyishou/Gsnake Play On: http://zhiyishou. ...