1.程序地址空间

       首先,我们先看学c/c++时候学到的程序内存布局:

 

  准确地说,程序地址空间其实就是进程的地址空间,实际就是pcb中的mm_struct

  接下来,我们用fork()演示一下进程的地址空间。

   //父子进程数据独有demo 
1 #include<stdio.h>
#include<stdlib.h>
#include<unistd.h> int g_val = ;
int main()
{
int pid=fork();
if(pid < )
{
return -;
}else if(pid == )
{
//child
g_val = ;
printf("child val: %d--%p\n",g_val,&g_val);
}
else
{
//parent
sleep();
printf("parent val:%d--%p\n",g_val,&g_val);
}
return ;
}

     很容易看出,父子进程的地址是一样的,但是变量的值却不一样。

      由此能推出 : 我们所看到的地址并不是真实的物理地址

          Linux下,我们称作为虚拟地址

       说明进程访问的地址都是虚拟地址,物理地址我们用户是看不到的,由操作系统负责物理地址和虚拟地址的转换

  

  2.进程地址空间实现原理 --- 利用内存碎片

    通过上面测试,我们肯定要问,为什么要使用虚拟地址呢?

    1.增加内存访问控制 --- 如果进程可以使用任意的物理内存,意味着如果木马病毒进来了,就可以修改内存空间让电脑瘫痪,很不安全。

       2.提高内存利用率 --- 如何利用内存碎片,榨干计算机性能,一直是计算机发展史中的一个重要问题,下面会给大家讲讲如何提高内存利用率。

            3.保证进程独立性 --- 用物理地址的话,地址难以确定,有了虚拟地址,进程都可以拥有自己的一套虚拟地址,能让程序员更好地编码。

    既然虚拟地址这么好用,那来看看它的实现原理吧!

       在Linux下,OS使用的是分页式内存管理

       内存分页: 

      为什么要有分页 --- 物理地址和虚拟地址的分离,给进程带来了安全和便利,但是他们之间的转换如果是按字节一一对应记录的,那么要消耗的额外资源就太多了

      分页是什么 --- 以更大尺寸的单位页来管理内存,这个单位页负责物理地址与虚拟地址的映射关系,Linux中通常每页大小为4KB。下面是我Linux下测出的大小。

      分页的原理 --- 因为物理页和虚拟页内地址肯定是连续的,所以页内数据可以按顺序一一对应。

               因为页表大小都是一样的,所以页内数据的末尾地址都是相同的(二进制下后12位都为1),我们把这个地址称之为偏移量。

               偏移量实际上表达了该字节在页内的位置。

               地址的前一部分则是页编号,后一部分是页内偏移。

             页表记录页编号和物理块编号的对应关系。

               虚拟页编号在页表中找到对应的物理块编号,再计算出页内偏移,就可得到实际物理地址。

             物理地址 = 块编号*块大小 + 偏移量 

      分页优化: 多级分页表 ---  分页让我们将逻辑地址和物理地址分离,能更好的进行内存管理。

                   我们知道进程都会有一套虚拟内存地址(mm_struct),那么其中肯定包含了分页表保存所有分页,为了保证查询效率,分页表会保存于内存中。

                   并且,堆栈上有很多空间都是进程预留的,意味着如果使用连续分页表,很多条目都没有真正用到

                   因此,Linux中的分页表,采用了多层的数据结构多层的分页表能够减少所需的空间

                  

                  用上图的二级表结构举个例子,页编号被分为两级:

                       一级表: 一级页编号保存地址的前8位(十六进制2位),一级表负责映射该地址下的二级表地址。

                     二级表: 二级表编号保存地址的后12位(十六进制3位),二级表负责映射该地址下的物理地址。

                  上面我们了解到,连续的分页表可以直接通过虚拟页编号找到物理页编号,而二级分页表,我们要先拿出虚拟页编号前8位编号在一级表中找到对应的二级表,再拿出虚拟页编号后12位在二级表找到对应的物理地址。就像身份证号,每个地区的前6位都是一样的,如果要查某人的身份证号,先查地区,再查人,能大大减少查找量,如上图0x01为空,说明这个地区没人,那么相应的二级表也不需要存在。这样,二级表所占数据就会比连续单页表少多了

                  二级表还有一个优点: 因为是多层结构,所以不必像单层表一样占据一整块内存,而是可以存于不同位置,提高内存利用率。

      

                  

 

  

      

            

     

      

        

   

  

  

 

  

  

  

  

   

   

Linux 进程地址空间及原理的更多相关文章

  1. linux进程地址空间详解(转载)

    linux进程地址空间详解(转载) 在前面的<对一个程序在内存中的分析 >中很好的描述了程序在内存中的布局,这里对这个结果做些总结和实验验证.下面以Linux为例(实验结果显示window ...

  2. UNIX环境高级编程——Linux进程地址空间和虚拟内存

    一.虚拟内存 分段机制:即分成代码段,数据段,堆栈段.每个内存段都与一个特权级相关联,即0~3,0具有最高特权级(内核),3则是最低特权级(用户),每当程序试图访问(权限又分为可读.可写和可执行)一个 ...

  3. Linux进程地址空间和虚拟内存

    一.虚拟内存 先来看一张图(来自<Linux内核完全剖析>),如下: 分段机制:即分成代码段,数据段,堆栈段.每个内存段都与一个特权级相关联,即0~3,0具有最高特权级(内核),3则是最低 ...

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

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

  5. Linux进程地址空间与虚拟内存

    http://blog.csdn.net/xu3737284/article/details/12710217 32位机器上linux操作系统中的进程的地址空间大小是4G,其中0-3G是用户空间,3G ...

  6. Linux进程地址空间 && 进程内存布局[转]

    一 进程空间分布概述       对于一个进程,其空间分布如下图所示: 程序段(Text):程序代码在内存中的映射,存放函数体的二进制代码. 初始化过的数据(Data):在程序运行初已经对变量进行初始 ...

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

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

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

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

  9. 《Linux性能及调优指南》----1.1 Linux进程管理

    翻译:飞哥 ( http://hi.baidu.com/imlidapeng ) 版权所有,尊重他人劳动成果,转载时请注明作者和原始出处及本声明. 原文名称:<Linux Performance ...

随机推荐

  1. H5注意点(1)

    H1标签在企业开发中,每一个页面至多只能有一个H1标签,被H1标签包裹的是整个页面最重要的信息. img标签,格式:<img src=" ">,当中src就是用来告诉i ...

  2. 百度编辑器contentChange监听不到图片上传

    将ueditor组件化到java项目中,当调用组件后,绑定函数,监听contentchange如下图: um.addListener("contentChange",functio ...

  3. excel自增编号

    1.首先在单元格 A2:C2 中输入数据. 2.选择 A3:A500, 我们按键盘的 CTRL G 键, 拉起定位框, 然后在参考位置, 输入 A3:A500, 然后单击 "确定" ...

  4. Oracle数据库启动报错,找不到数据文件(ORA-01157和ORA-01110)

    数据库报了ORA-01157和ORA-01110错误,提示找不到一个数据文件. 1.启动数据库报错 在启动数据库过程中,报了ORA-01157和ORA-01110错误,提示找不到数据文件. SQL&g ...

  5. Windows 操作系统 快捷键

    窗口放大缩小:  + ↑↓ 最小化窗口: ALT + Esc 关闭窗口: Alt + F4 搜索功能:  + 直接输入搜索内容 打开文件管理器:  + E 在文件管理器中切换: Tab

  6. git---主分支同步到子分支

    在进行git项目协同开发的时候,每个分支的代码会被合并到主分支 master 分支上,但是如何将master分支上的代码合并到子分支上呢? 第一步:切换到本地的仓库,更新为最新的代码. 第二步:切换到 ...

  7. java 数据相除

    编程的人都知道,java中的“/”.“%”运算,其中前者为取整,后者取余数.那么有没有快捷的运算方法取正常的运算结果呢? /** * TODO 除法运算,保留小数 * @author 袁忠明 * @d ...

  8. ActiveMQ之三--JMS-Spring和ActiveMQ整合的完整实

    这篇博文,我们基于Spring+JMS+ActiveMQ+Tomcat,做一个Spring4.1.0和ActiveMQ5.11.1整合实例,实现了Point-To-Point的异步队列消息和PUB/S ...

  9. 算法习题---5.9数据库(Uva1592)

    一:题目 对数据库中数据进行检测,是否出现数据冗余现象.即是否某一列出现两个及以上数据重复 如上图中,第二列中第2,3行数据重复,所以我们判断为数据冗余.因为他可以分解为下面两张表 (一)样例输入 H ...

  10. 【翻译】Flink Joining

    本文来自官网翻译: Joining Window Join(窗口join) Tumbling Window Join(翻滚窗口join) Sliding Window Join(滑动窗口join) S ...