进程虚拟地址空间

本文详细介绍了虚拟内存的工作原理,包括地址转换过程、Linux下虚拟地址空间的结构以及mm_struct的角色。重点讲解了如何通过分段管理虚拟地址空间,涉及代码段、数据段、堆、内存映射区和栈。同时揭示了内核如何通过mm_struct来组织和控制这些内存区域。
摘要由CSDN通过智能技术生成
1. 虚拟内存概述

虚拟内存是计算机系统内存管理的一种技术,它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),这使得系统管理多进程的内存请求更加方便且高效。Linux操作系统为每一个进程提供一个固定大小、私有的虚拟地址空间,虚拟地址空间包含了当前进程需要的所有数据信息,然而虚拟内存指向的数据并非所有的都加载到主存中,一部分数据仅仅是记录了该数据在磁盘的起始位置以及大小,需要的时候由内核负责读入主存,同样的,内核也会在该内存不需要访问的时候将其回写磁盘,空出来共其他内存请求。正是这个原理,有限的主存可以保证多个进程同时运行或者高于主存的内存申请。

2. 虚拟内存与物理内存转换

在这里插入图片描述

如上是虚拟地址(VA)到物理地址(PA)再通过数据总线获取到数据的架构图,其中MMU(Memory Management Unit,内存管理单元)负责地址的转换,其中还会涉及到更深层次的细节,如TLB命中PTE查询、缺页异常处理等,本文不展开讨论。其基本过程就是执行单元通过地址总线向主存请求数据,对于具有MMU模块的系统架构来说,MMU拦截当前的请求,并完成VAPA的转换,然后向主存请求数据,CPU通过数据总线获取数据,这一过程无论是对于上层应用还是CPU执行单元都是无感的过程。

3. 如何描述虚拟地址空间

为了更有效率的管理虚拟地址空间,系统根据数据的性质以及权限等考量,将虚拟地址空间通过分段的方式划分不同的段,如下是一个32位机器的虚拟地址分段展示图:
在这里插入图片描述
上面的虚拟地址空间仅仅抽象的描述,那么内核如何完成如上的描述呢?我们都知道内核通过task_struct描述一个进程,其中就使用一个成员变量描述该进程对应的虚拟地址空间:struct mm_struct *mm。进程虽说都独占4G的虚拟地址空间,实际上内核空间是每个进程共享的,所以这里主要探讨的是剩下来的3G的用户空间。每个进程都有6个分段:

  • 代码段(Text):用来存放程序二进制执行代码的内存区域,同时还包括一些只读的常数变量,如字符串,该区域通常为只读权限
  • 数据段(Data):保存已初始化的全局变量或者是静态变量
  • BSS(Block Started by Symbol):保存未初始化的全局变量或者是静态变量
  • (Heap):用于保存运行时被手动分配的变量,该内存段大小并不固定,调用malloc/free会增大/缩小该区域
  • 内存映射区(Memory Mapping Segment):该区域主要是一些动态库的映射,或者通过mmap映射的一段内存区域
  • (Stack):由编译自动分配的变量,如函数中申明的局部变量

内核中通过vm_area_struct描述进程地址分段,mm_struct使用struct vm_area_struct *mmap通过链表的方式记录全部的VMA
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值