Linux 进程地址空间及原理
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 进程地址空间及原理的更多相关文章
- linux进程地址空间详解(转载)
linux进程地址空间详解(转载) 在前面的<对一个程序在内存中的分析 >中很好的描述了程序在内存中的布局,这里对这个结果做些总结和实验验证.下面以Linux为例(实验结果显示window ...
- UNIX环境高级编程——Linux进程地址空间和虚拟内存
一.虚拟内存 分段机制:即分成代码段,数据段,堆栈段.每个内存段都与一个特权级相关联,即0~3,0具有最高特权级(内核),3则是最低特权级(用户),每当程序试图访问(权限又分为可读.可写和可执行)一个 ...
- Linux进程地址空间和虚拟内存
一.虚拟内存 先来看一张图(来自<Linux内核完全剖析>),如下: 分段机制:即分成代码段,数据段,堆栈段.每个内存段都与一个特权级相关联,即0~3,0具有最高特权级(内核),3则是最低 ...
- linux 进程地址空间的一步步探究
我们知道,在32位机器上linux操作系统中的进程的地址空间大小是4G,其中0-3G是用户空间,3G-4G是内核空间.其实,这个4G的地址空间是不存在的,也就是我们所说的虚拟内存空间. 那虚拟内存空间 ...
- Linux进程地址空间与虚拟内存
http://blog.csdn.net/xu3737284/article/details/12710217 32位机器上linux操作系统中的进程的地址空间大小是4G,其中0-3G是用户空间,3G ...
- Linux进程地址空间 && 进程内存布局[转]
一 进程空间分布概述 对于一个进程,其空间分布如下图所示: 程序段(Text):程序代码在内存中的映射,存放函数体的二进制代码. 初始化过的数据(Data):在程序运行初已经对变量进行初始 ...
- linux进程地址空间--vma的基本操作【转】
转自:http://blog.csdn.net/vanbreaker/article/details/7855007 版权声明:本文为博主原创文章,未经博主允许不得转载. 在32位的系统上,线性地址空 ...
- Linux进程虚拟地址空间管理2
2017-04-12 前篇文章对Linux进程地址空间的布局以及各个部分的功能做了简要介绍,本文主要对各个部分的具体使用做下简要分析,主要涉及三个方面:1.MMAP文件的映射过程 2.用户 内存的动态 ...
- 《Linux性能及调优指南》----1.1 Linux进程管理
翻译:飞哥 ( http://hi.baidu.com/imlidapeng ) 版权所有,尊重他人劳动成果,转载时请注明作者和原始出处及本声明. 原文名称:<Linux Performance ...
随机推荐
- win10下Python安装pycrypto报错
错误一: error: Microsoft Visual C++ 14.0 is required. 解决办法: 下载Visual C++2017安装包,下载链接:Visual C++ 2017 安 ...
- 003 spring boot访问静态资源与重定向
今天被问到重定向的问题,后续又引起了静态资源路径配置的问题,在这里做一个总结,当然,顺便添加默认访问index.html. 一:默认访问 1.默认路径 在springboot中静态资源的映射文件是在r ...
- leetcode 611. Valid Triangle Number 、259. 3Sum Smaller(lintcode 918. 3Sum Smaller)
这两个题几乎一样,只是说611. Valid Triangle Number满足大于条件,259. 3Sum Smaller满足小于条件,两者都是先排序,然后用双指针的方式. 611. Valid T ...
- 一起入门Python1之python的介绍
之前在某安全论坛发表的一些关于python的文章,但是由于一些问题一直没有完成,那个论坛也歇菜了.放到这儿来吧. 说句默心掏肺的话,我也是才学习python.之所以要这个版主,是为了锻炼自己,也是为了 ...
- Eclipse SDK目录
SDK standard developer kits 标准的开发工具 ---类似JDK 1.add-ons 这里面保存着附加库,比如GoogleMaps,当然你如果安装了OphoneSDK,这里 ...
- ISO/IEC 9899:2011 条款6.7.4——函数说明符
6.7.4 函数说明符 语法 1.function-specifier: inline _Noreturn 约束 2.函数说明符应该只能被用在对一个函数标识符的声明中. 3.对一个含有外部连接函数的内 ...
- Asp.Net Core 2.2 - HTTP Error 500.0 - ANCM In-Process Handler Load Failure
检查发布文件下是否存在runtime这个文件夹,如图
- Spring cloud微服务安全实战-3-5 API安全机制之认证(2)
基于Http协议的认证方式有很多.本节我们只讲一个最简单的HttpBasic认证.聪明就可以看出来,这是一个最基础的认证,好处是简单方便,所有的主流浏览器都支持,问题就是并不是非常安全的,但是帮我们大 ...
- 算法习题---4-10洪水(UVa815)
一:题目 有一个n*m(<=n,m<=)的网格,每个格子都是边长为10米的正方形,网格四周是无限大的墙壁.输入每个格子的海拔高度,以及网格内雨水的总体积,输出水位的海拔高度以及有多少百分比 ...
- JDK1.7 和JDK1.8同时存在设置默认的JDK
最近学习SpringCloud需要安装JDK1.8 但是自己的项目在1.8的环境中运行不了 无论怎么修改使用cmd 中命令的java -version 都显示是jdk 1.8 将java home ...