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 ...
随机推荐
- mysql数据库出现无法登录(ERROR 1045 ),预防和解决及系列问题解决方法。
一 .当在windows下使用mysql数据库时,出现无法登录的现象,需要修改mysql数据库的roo密码时,我们可以使用一下两种方法. 1. (1)关闭mysql服务.然后在bin目录下使用cm ...
- FIS3
#npm install -g cnpm --registry=https://registry.npm.taobao.org#cnpm install -g fis3 npm install fis ...
- python简单图形界面GUI入门——easygui【转】
原文:https://blog.csdn.net/mingqi1996/article/details/81272621 感觉gui做起来成就感比较高,学完基础语言顺便花一个下午看看GUI设计,现在回 ...
- onenote架设在局域网服务器
1.服务器端工作 1.1.在局域网服务器磁盘建个 文件夹,命名为 abc 1.2.右键共享,添加用户everyone 权限设置为可读写 不需要安装onenote 2.客户端工作 2.1.在客户端服务器 ...
- 搭建Nuxt项目(搭配Element UI、axios)
使用Nuxt Nuxt.js文档:https://zh.nuxtjs.org/guide/ 开始 初始化Nuxt项目 npx create-nuxt-app <项目名> // or yar ...
- Python脚本基础运算和算法
原文地址:https://www.cnblogs.com/ailiailan/p/10141741.html 通过关注“常见”脚本,是对代码的一个很好的学习和总结的方式. 1.冒泡排序 lis = [ ...
- Spring Boot CLI——centos7
Spring Boot是一个命令行工具,用于使用Spring进行快速原型搭建.它允许你运行Groovy脚本,这意味着你可以使用类Java的语法,并且没有那么多的模板代码. 所有版本下载地址这里下载的版 ...
- Docs-.NET-C#-指南-语言参考-预处理器指令:#region(C# 参考)
ylbtech-Docs-.NET-C#-指南-语言参考-预处理器指令:#region(C# 参考) 1.返回顶部 1. #region(C# 参考) 2015/07/20 利用 #region,可以 ...
- Python3基础 函数 参数 多个参数都有缺省值,需要指定参数进行赋值
Python : 3.7.3 OS : Ubuntu 18.04.2 LTS IDE : pycharm-community-2019.1.3 ...
- 008-MySQL报错-Access denied for user 'root'@'localhost' (using password: NO)
1.新安装的mysql报错 MySQL报错-Access denied for user 'root'@'localhost' (using password: NO) 解决方案 1.先停掉原来的服务 ...