Linux:程序地址空间初步了解


前言

本文所研究均基于kernel 2.6.32 和 32位平台
程序地址空间在某种意义上称作进程地址空间或虚拟地址空间更为合适
程序地址空间是一个程序在执行期间可以访问的内存范围,它由操作系统为每个进程分配,本质上是一个数据结构,以确保进程之间不会相互干扰。


一、定义和概念

程序地址空间包含了程序所需的所有内存区域,这些区域包括代码段、数据段(包括已初始化和未初始化的数据)、堆(heap)、栈(stack)等。每个进程都有自己独立的程序地址空间.。
在这里插入图片描述

  • 代码段:存放程序的机器指令。这些指令在程序执行期间被CPU读取并执行。
  • 数据段:存放程序中已初始化的全局变量和静态变量。这些变量在程序执行期间被程序访问和修改。
  • 未初始化数据段(BSS段):存放程序中未初始化的全局变量和静态变量。这些变量在程序执行前由操作系统初始化为零。
  • 堆(heap):用于动态分配内存的区域。程序员可以通过调用内存分配函数(如malloc、new等)在堆上申请内存空间。
  • 栈(stack):用于存储函数调用时的局部变量、函数参数以及返回地址等。栈是自动管理的,当函数调用结束时,栈上的内存会自动释放。
    注意程序地址空间并不是内存,内存是一种物理地址&&线性地址,程序地址空间是一种虚拟地址,程序地址空间中的虚拟地址需要通过操作系统的地址映射机制转换为物理地址

1.1 cpu和内存之间联系

在32位机器中,有32位地址和数据总线,cpu和内存是独立的器件单元,它们靠着线连接,每一根线在软件层面上能够表示 0 | 1两种状态,而cpu能根据一次性地址传递的32个状态在内存上寻找到相应的地址,所以它有2^32种状态,对应内存寻址就是4GB

二、进程地址空间

2.1 宏观了解进程地址空间

每个进程在创建的时候都会包含一个指针成员变量,这个指针会指向一个进程地址空间,这个是语言层面上的地址
nvc 55
在这里插入图片描述

如果这个进程内部创建了子进程,那么子进程会拥有和父进程一样的进程地址空间,所以通过某种映射关系会获得与父进程所在的物理内存上相同的地址,这代表子进程的数据和代码会和父进程一样。但是当我们子进程对非进程内部创建的数据做修改的时候又会发生写时拷贝的操作,相当于在物理地址上新开辟个地址,并改变进程地址空间中地址与之相对的映射关系。

2.3 地址空间概念 && 区域划分概念

由1.1可知地址总线排列形成的地址范围[0,2^32],及32位机器下的内存大小。
32位机器的地址空间是指其CPU能够寻址的内存范围。

地址空间本质是内核的一种数据对象,类似PCB一样,要被操作系统管理:先描述,在组织
地址空间中一定存在各种区域划分,对线性地址的每个区域进行start,end即可。
在这里插入图片描述
mm_struct结构是对整个⽤⼾空间的描述。每⼀个进程都会有⾃⼰独⽴的mm_struct,这样每⼀个进程都会有⾃⼰独⽴的地址空间才能互不⼲扰。
在这里插入图片描述
页表(Page Table)是操作系统用于存储虚拟地址到物理地址映射的数据结构。因为有了页表的存在,父进程的环境变量和命令行参数也能在子进程中找到。

2.3 虚拟内存管理

⼀个进程都会有⾃⼰独⽴的mm_struct,操作系统肯定是要将这么多进程的mm_struct组织起来的!虚拟空间的组织⽅式有两种:

  1. 当虚拟区较少时采取单链表,由mmap指针指向这个链表;
  2. 当虚拟区间多时采取红⿊树进⾏管理,由mm_rb指向这棵树。
    在这里插入图片描述
    在这里插入图片描述

虚拟内存的作用:
1. 让每个进程以同一的视角去面对内存结构
2. 增加一个虚拟地址空间可以让我们在访问内存的时候,增加一次地址转换的过程,在这个过程中可以对我们寻址请求进行审查,所以一旦异常访问直接拦截,该请求不会到达物理内存,保护物理内存
3. 因为有页表和地址空间的存在,将内存管理模块和进程管理模块解耦合,两者高度配合但又互不影响


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值