Linux虚拟内存和进程虚拟地址空间简述

后台开发经常会问此类问题,虽说难度不大,但是知道和不知道还是有区别的。以下的内容总结自《深入理解Linux内核》第一章,仅仅是简述,没有深入研究,毕竟内存管理这一块内容超级多,感兴趣的同学可以去啃啃这本书。

  1. 虚拟内存

所有新近的Unix系统都提供了一种有用的抽象,叫虚拟内存(virtual memory)。虚拟内存作为一种逻辑层,处于应用程序的内存请求与硬件内存管理单元(Memory Management Unit, MMU)之间。虚拟内存有很多用途和优点:

  • 若干个进程可以并发地执行。
  • 应用程序所需内存大小大于可用物理内存时也可以运行。
  • 程序只有部分代码装入内存时进程也可以执行它。
  • 允许每个进程访问可用物理内存的子集。
  • 进程可以共享库函数或程序的一个单独内存映像。
  • 程序是可重定位的,也就是说,可以把程序放在物理内存的任何地方。
  • 程序员可以编写与机器无关的代码,因为他们不必关心物理内存的组织结构。

虚拟内存子系统的主要成分是虚拟地址空间(virutal address space)的概念。进程所用的一组内存地址不同于物理内存地址。当进程使用一个虚拟地址时,内核和MMU协同定位其在内存中的实际物理位置。

现在的CPU包含了能自动把虚拟地址转换成物理地址的硬件电路。为了达到这个目标,把可用RAM划分成4KB或8KB的页框(page frame),并且引入一组页表来指定虚拟地址和物理地址之间的对应关系。这些电路使得内存分配变得简单,因为一块连续的虚拟地址请求可以通过分配一组非连续的物理地址页框而得到满足。

2.        进程虚拟地址空间处理

进程的虚拟地址空间包括了进程可以引用的所有虚拟内存地址。内核通常用一组内存区描述符(mm_struct)描述进程虚拟地址空间。例如,当进程通过exec()类系统调用开始某个程序的执行时,内核分配给进程的虚拟地址空间由以下几个内存区组成:

  • 程序的可执行代码。
  • 程序的初始化数据。
  • 程序的未初始化数据。
  • 初始程序栈(即用户态栈)
  • 所需共享库的可执行代码和数据(此部分并不实际拷贝,仅仅时映射)
  • 堆(由程序动态请求的内存)

所有现代Unix操作系统都采用了所谓请求调页(demand paging)的内存分配策略。有了请求调页,进程可以在它的页还没有在内存时就开始执行。当进程访问一个不存在的页时,MMU产生一个异常:异常处理程序找到受影响的内存区,分配一个空闲的页,并用适当的数据把它初始化。同理,当进程通过malloc或者brk系统调用动态的请求内存时,内核仅仅修改进程的堆内存区的大小。只有试图引用进程的虚拟内存地址而产生异常时,才给进程分配页框。

参考目录:

1. 《深入理解Linux内核》

2. 《Linux设备驱动程序》​​​​​​​

=============================================================================================

Linux应用程序、内核、驱动、后台开发交流讨论群(745510310),感兴趣的同学可以加群讨论、交流、资料查找等,前进的道路上,你不是一个人奥^_^。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值