Linux进程地址空间和虚拟内存
一、虚拟内存
先来看一张图(来自《Linux内核完全剖析》),如下:
分段机制:即分成代码段,数据段,堆栈段。每个内存段都与一个特权级相关联,即0~3,0具有最高特权级(内核),3则是最低特权级(用户),每当程序试图访问(权限又分为可读、可写和可执行)一个段时,当前特权级CPL就会与段的特权级进行比较,以确定是否有权限访问。每个特权级都有自己的程序栈,当程序从一个特权级切换到另一个特权级上执行时,堆栈段也随之改换到新级别的堆栈中。
段选择符:每个段都有一个段选择符。段描述符指明段的大小、访问权限和段的特权级、段类型以及段的第一个字节在线性地址空间中的位置(称为段的基地址)。而段选择符用于在描述符表中进行索引找到段描述符。
虚拟地址:虚拟地址的偏移量部分加上段的基地址上就可以定位段中某个字节的位置,即形成线性地址空间中的地址。
分页机制:当使用分页机制时,每个段被划分成页面(通常每页在4KB大小),页面会被存储于物理内存或硬盘上。如果禁用分页机制,那么线性地址空间就是物理地址空间。
当程序试图访问线性地址空间上的一个地址位置时,发生以下操作:
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
if(数据在物理内存中)
{ 虚拟地址转换成物理地址 读数据 } else { if(数据在磁盘中) { if(物理内存还有空闲) { 把数据从磁盘中读到物理内存 虚拟地址转换成物理地址 读数据 } else { 把物理内存中某页的数据存入磁盘 把要读的数据从磁盘读到该页的物理内存中 虚拟地址转换成物理地址 读数据 } } else { 报错 } } |
其中MMU负责虚拟地址到物理地址的转换工作,分段和分页操作都使用驻留在内存中的段表和页表来指定他们各自的交换信息。如果用户程序想要访问一个虚拟地址,经MMU检查无权访问(特权级),MMU产生一个异常,CPU从用户模式切换到特权模式,跳转到内核代码中执行异常服务程序,内核把这个异常解释为段错误,把引发异常的进程终止掉。


二、linux进程地址空间
由前面可得知,进程有4G的寻址空间,其中第一部分为“用户空间”,用来映射其整个进程空间(0x0000 0000-0xBFFF FFFF)即3G字节的虚拟地址;第二部分为“系统空间”,用来映射(0xC000 0000-0xFFFF FFFF)1G字节的虚拟地址。如下图
将其更加详细地展示如下:
程序路径:完整的绝对路径字符串如 “/home/simba/code/asm/simple”
环境变量:类似linux下的PATH,HOME等的环境变量,子进程会继承父进程的环境变量。
命令行参数:类似ls -l 中-l 就是命令行参数,而ls 就是可执行程序。
栈:就是堆栈,程序运行时需要在这里做数据运算,存储临时数据,开辟函数栈等。在Linux下,栈是高地址往低地址增长的。
对于函数栈来说,函数运行完毕就释放内存,举例递归来说,一直开辟向下函数栈,然后由下往上收复,所以递归太多层的话很可能造成栈溢出。
局部变量(不包含静态变量);局部可读变量(const)都分配在栈上。
共享库和mmap内存映射区:比如很多程序都会用到的printf,函数共享库 printf.o 固定在某个物理内存位置上,让许多进程映射共享。mmap是个系统函数,可以把磁盘文件的一部分直接映射到内存,这样文件中的位置直接就有对应的内存地址,对文件的读写可以直接用指针来做而不需要read/write函数。此外,调用malloc 时正常是调用brk 系统调用分配内存,特定条件下是调用mmap
来映射物理内存到进程地址空间。
堆:即malloc申请的内存,使用free释放,如果没有主动释放,在进程运行结束时也会被释放。
Text Segment: 可执行程序(二进制)(.text);全局初始化只读变量(const)(.rodata);字符串常量(.rodata);均在这里分配。
Data Segment: 全局变量(初始化的在.data,未初始化的在.bss);静态变量(全局和局部)(初始化的在.data,未初始化的在.bss);全局未初始化只读变量(.bss);均在这里分配。
Linux进程地址空间和虚拟内存的更多相关文章
- UNIX环境高级编程——Linux进程地址空间和虚拟内存
一.虚拟内存 分段机制:即分成代码段,数据段,堆栈段.每个内存段都与一个特权级相关联,即0~3,0具有最高特权级(内核),3则是最低特权级(用户),每当程序试图访问(权限又分为可读.可写和可执行)一个 ...
- Linux进程地址空间与虚拟内存
http://blog.csdn.net/xu3737284/article/details/12710217 32位机器上linux操作系统中的进程的地址空间大小是4G,其中0-3G是用户空间,3G ...
- linux进程地址空间详解(转载)
linux进程地址空间详解(转载) 在前面的<对一个程序在内存中的分析 >中很好的描述了程序在内存中的布局,这里对这个结果做些总结和实验验证.下面以Linux为例(实验结果显示window ...
- linux 进程地址空间的一步步探究
我们知道,在32位机器上linux操作系统中的进程的地址空间大小是4G,其中0-3G是用户空间,3G-4G是内核空间.其实,这个4G的地址空间是不存在的,也就是我们所说的虚拟内存空间. 那虚拟内存空间 ...
- Linux进程地址空间 && 进程内存布局[转]
一 进程空间分布概述 对于一个进程,其空间分布如下图所示: 程序段(Text):程序代码在内存中的映射,存放函数体的二进制代码. 初始化过的数据(Data):在程序运行初已经对变量进行初始 ...
- linux进程地址空间--vma的基本操作【转】
转自:http://blog.csdn.net/vanbreaker/article/details/7855007 版权声明:本文为博主原创文章,未经博主允许不得转载. 在32位的系统上,线性地址空 ...
- Linux 进程地址空间及原理
1.程序地址空间 首先,我们先看学c/c++时候学到的程序内存布局: 准确地说,程序地址空间其实就是进程的地址空间,实际就是pcb中的mm_struct. 接下来,我们用fork()演示一下 ...
- Linux进程虚拟地址空间管理2
2017-04-12 前篇文章对Linux进程地址空间的布局以及各个部分的功能做了简要介绍,本文主要对各个部分的具体使用做下简要分析,主要涉及三个方面:1.MMAP文件的映射过程 2.用户 内存的动态 ...
- linux 进程(一)---基本概念
一.进程的定义 进程是操作系统的概念,每当我们执行一个程序时,对于操作系统来讲就创建了一个进程,在这个过程中,伴随着资源的分配和释放.可以认为进程是一个程序的一次执行过程. 二.进 ...
随机推荐
- MediaPlayer 状态机 API 详解 示例
简介 public class android.media.MediaPlayer extends Object implements VolumeAutomation 可能需要的权限: One ma ...
- JavaScript生成GUID的方法
一.生成GUID的方法一 JScript 代码 复制 function guid() { function S4() { return (((1+Math.random())*0x1000 ...
- vue-router路由知识补充
1.render函数 var app = new Vue({ el: '#app', router, render: h => h(App) //新添加的函数操作 }) 我们新加了render: ...
- qt creator修改程序编码(解决中文乱码问题)的方法
qt creator修改程序编码(解决中文乱码问题)的方法 qt creator修改程序编码的功能有几处. 1.edit - select encoding 选择载入(显示)编码和储存编码,其中GB2 ...
- c语言基础,\r, \n, \r\n
Enumeration (or enum) in C Enumeration (or enum) is a user defined data type in C. It is mainly used ...
- Cognos开发图表乱码问题
在此之前提到过在利用TR建模导入IQD数据源的时候遇到乱码的一种解决方案: http://www.cnblogs.com/wxjnew/p/3374029.html 今天说的是在RS中开发新报表的时候 ...
- 在陌生Linux环境查看Tomcat服务的方法
1.查看Tomcat进程 执行命令$ps -ef|grep tomcat 你就能找出tomcat占据的进程号,当然这要求tomcat启动了. # ps -ef | grep tomcatroot ...
- C#.NET常见问题(FAQ)-list比数组效率低多少
对于List,即长度不确定的数组而言,十万笔数据*12倍,就是120万笔数据,只需要93ms左右 换成了二维数组,效果也是差不多,78ms,可见list的效率只比double差一点点 更多 ...
- C#.NET常见问题(FAQ)-如何批量增加或取消注释
选中一批文本之后 批量增加注释:Ctrl+K Ctrl+C 批量取消注释:Ctrl+K Ctrl+U 更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http://i.youku. ...
- ZH奶酪:Yii PHP sum SQL查询语句
例子: $sql = 'SELECT SUM(o.price) as `sum` FROM `order` o WHERE o.customer_id ='.$profile->id; $ret ...