第十五章-进程地址空间-linux内核设计与实现

地址空间

  • 把有相同地址空间的进程称为线程
  • 一个进程访问了不在有效范围中的内存区域,或者以不正确的方式访问了有效地址,那么内核就会终止进程

内存区域包含的内存对象

  • 代码段:可执行文件代码的内存映射
  • 数据段:可执行文件已经初始化的全局变量内存映射
  • 未初始化的全局变量
  • 进程的用户空间栈(注意进程的内核栈独立存在,由内核维护)
  • C库或者动态连接程序等共享库的代码段
  • 内存映射文件
  • 共享内存段
  • 匿名的内存映射

内存描述符

  • 内存描述符mm_struct结构体表示进程地址空间

mm_strcut

  • mm_user记录使用该地址空间进程数
  • mm_count表示mm_struct主引用计数,0表示没有线程使用这个地址空间,1表示有

分配内存描述符

  • 通常每个进程都有唯一的mm_struct结构体,也就是唯一的地址空间
  • 如果父进程希望和子进程共享地址空间,可以在调用clone 时设置CLONE_VM标志,那么这样的进程就变成线程了,实际上这样子进程的mm域就指向父进程的内存描述符

撤销内存描述符

  • 每次进程退出就会更新一些统计量,减少mm_user如果减少到为0,那么说明这个内存描述符没有进程使用了,于是调用对应函数将内存描述符释放回slab分配器。

mm_struct与内核线程

  • 内核线程没有进程地址空间,没有内存描述符,实际上内核线程–没有用户上下文???
  • 但内核线程访问内核内存害是需要一些数据,比如页表,所以为了避面浪费内存,和地址空间切换,直接使用前一个进程的内存描述符???

虚拟内存区域VMA

  • 实际上就是把地址空间再分多个区域,每个区域意义不同,比如代码段,用户空间栈。把每个内存区域当做对象管理,有访问权限,操作函数,起始地址和结束地址。使用面向对象思想

VM标志

  • 标志内存区域的的行为和信息

存储内存区域的数据结构

  • 链表用于方便遍历地址空间的所有内存区域
  • 红黑树方便,用于查找某个地址在哪个内存区域
  • 寻找某个地址在哪个内存区域,还使用了缓存技术,考虑可能有多个连续的对同一个VMA的操作

mmap do_mmap

do__mmap

  • 内核使用do_mmap()函数创建新的线性地址空间
  • 该函数映射由file指定的文件,具体映射的是文件从偏移量offset开始长度为len字节内的数据
  • 如果file = NULL,offset = 0 叫做匿名映射,否则是文件映射,addr搜索空间的起始位置,prot参数指定访问权限
    具体实现
  • 从虚拟内存中分配一个合适的新的内存区域,如果创建的地址区间和已经存在的相邻,且有相同访问权限,那么就合并。
  • 不能合并就从slab中分配一个对应的结构体代表这个区域
  • 更新地址空间内存区域链表和红黑树,更新内存描述符中对应的域
  • 返回新分配的地址区间的起始位置

mmap系统调用

  • 实际上实现的是和do_map一样的功能

munmap 和 do_munmap

  • 和上面的相反,就是在特定地址空间中删除指定地址区域

页表

  • 应用程序使用的是虚拟内存,处理器直接操作虚拟内存,所以需要查询页表找到物理地址
  • linux使用3级页表 为什么使用多级页表
  • fork进程中的写时拷贝技术,父子进程共享页表,当父子进程中的一方修改特定页表时,内核才去创建对应页表项的拷贝,之后不在共享这个页表项。通过共享页表可以消除fork操作中页表拷贝带来的消耗

为什么使用多级页表

  • 避免把全部页表保存在内存中,让页表在内存中离散存储,虚拟地址空间增大,页表数增大,存放页表的连续空间增大,操作系统内存紧张,或者碎片较多时,连续的大内存很宝贵,使用一页存放页表目录项,页表项可以放在内存中其他分散的碎片位置,不用保证页表连续。
  • 多级页表可以节省页表内存。因为地址空间在内存的哪个位置都有可能,如果用一级页表那么占用内存 = 内存大小/页大小 * 4 b 固定的。但是有的应用程序占用内存很小,比如4m。那么用多级页表 = 内存大小/应用程序大小 * 4b(一级页表:目录项) + 实际目录项指向的一个大小为4m/页大小(二级页表),但是这边也目录项并不是每一项都指向一个时间二级页表,可能为空,那么就不占内存,也就节约了内存。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值