linux内存管理技术
2022-11-08 22:28:30 13 举报
AI智能生成
linux内存管理技术脉络梳理
作者其他创作
大纲/内容
目标
确保多个并发进程实现安全高效的内存共享
提高内存利用率和内存寻址效率
内存管理技术
虚拟内存
直接内存访问的问题
恶意程序可随意读取和修改其他程序甚至操作系统的内存数据
非恶意程序可能无意中修改其他程序甚至操作系统的内存数据,导致程序运行异常或严重的系统安全问题
某个程序运行时发生崩溃,可能导致整个系统崩溃
间接访问内存
虚拟内存
虚拟地址
地址空间:一个进程可寻址的一套地址的集合
虚拟地址空间
用户空间
基本信息
地址空间的低位
512GB(2^39B)
0x0000 0000 0000 0000~0x0000 007F FFFF FFFF
作用
包含了进程的所有内存状态
结构
栈
堆
数据段
代码段
内核空间
基本信息
地址空间的高位
512GB(2^39B)
0xFFFF FF80 0000 0000~0xFFFF FFFF FFFF FFFF
作用
操作系统内核运行的地址空间
不可访问区域
64位虚拟地址空间未使用的部分
进程访问此区域时,硬件将触发异常
物理地址空间
好处
单一物理内存为每个进程提供了拥有全部内存的假象
为进程之间的隔离提供了基础
为操作系统介入检查访问地址是否合法提供了渠道
分页机制
基本思想
虚拟地址空间固定长度单元:页
物理地址空间固定长度单元:页框
每个进程记录页号和页框号映射关系的表:页表
好处
减少了内存碎片
页共享
带来的问题
空闲页框管理
buddy系统
优点
原理简单
外部碎片比较少
可分配连续物理内存
缺点
内部碎片问题比较严重
地址转换
虚拟地址:页号+页内偏移地址
页表项:PTE,大小与处理器理论支持最大物理内存的大小和页大小有关
页描述符:PTE+内存访问权限控制标志位
地址转换过程
从虚拟地址得到页号及偏移
用页号及页表基址寄存器获得PTE的物理地址
读取PTE值,获得页框号
利用页框号计算物理地址
软硬协同提升地址转换性能
硬件
由专用的硬件内存管理单元(MMU)完成页表查询
操作系统
建立页表,保存页表基址
设置页表基址寄存器
处理访存异常
内存访问控制
PTE内存访问权限控制属性
访问权限AP
不可执行XN
页的访问权限设置
代码段
只读,可执行(AP0b11,XN0b0)
数据段
可读写,不可执行(AP0b01,XN0b1)
用户空间与内核空间的隔离
内核地址空间PTE的AP字段初始化为0b00,仅允许高于EL1异常级访问
进程之间的隔离
进程的页表不同
TLB(地址转换旁路缓存)
目的
加快基于分页的内存访问地址转换过程
方法
MMU中增加TLB模块,存放最近访问过的虚拟地址对应的转换映射关系
原理
利用程序执行的局部性原理,减少页表查询次数
结构
进程隔离方法
每个进程运行时单独占有TLB
多个进程共享TLB,TLB条目中增加地址空间标识(ASID),与进程唯一对应
内核空间标记位nG,1位进程私有,0为全局映射
TLB表项基本构成:nG、VMID、ASID、页号、页框表
替换策略
随机替换策略
最近最久未使用策略
多级页表
目的
减少分页机制存储映射关系的页表消耗的内存
基本思想
将页表分成页大小的单元,只保留有效PTE
引入页目录,标记当前目录是否包含有效单元及有效单元所在位置
结构
PDE:页目录中每个条目
每条PDE指向由PTE组成的页
页目录如果仍很大,可增加一级页目录
寻址方式
页表基址寄存器
一级索引得到PDE
二级索引得到PTE
+页内偏移地址得到物理地址
优点
多级页表的实现方式可只为进程实际使用的虚拟内存地址创建页表信息,从而减少内存使用量
标准大页
目的
降低进程大内存需求下,进程管理的复杂性,提升运行效率
基本思想
增大分页粒度到MB甚至GB级别
实现方式
将多级页表中的某条PDE解释为块描述符
记录和管理
标准大页池
使用接口
伪文件系统hungetlbfs
挂载到文件系统,指向大页所分配的内存
用户可利用简单文件编程接口使用标准大页
缺点
大页的数量与长度必须在内核启动时指定,并预留大页池所需内存
用户需主动调用伪文件系统形式提供的接口申请大页,手动管理大页的申请与释放
透明大页
基本思想
为用户进程分配内存时,优先分配大页,不成功再回退分配普通页
实现方式
页错误机制
物理内存扩充
目的
实现以较小的物理内存空间来支持较大的进程虚拟空间
请求调页
目的
实现加载进程时只装入当前必须使用的页到内存,在运行过程中根据需要动态加载其他页
基本思想
PTE中新增字段标识页是否在内存中
如访问不在内存中的页,硬件产生异常,操作系统在对应的页错误处理程序中将相应的页调入内存
实现
PTE的有效标志位
aarch64架构下为PTE的bit[0]
MMU遇到无效的PTE,产生一个转换错误交由操作系统处理
页表初始化
初始化各级页表与标志位,指向新分配的页框
以双向链表存储一个进程的所有虚拟地址段信息
加载进程时,以可执行文件的ELF头部信息建立若干虚拟地址段
页错误(硬件职责)
MMU查到无效PTE后,触发转换错误
CPU将异常信息存入寄存器
根据异常向量表+偏移地址开始执行
页错误(操作系统职责)
读取异常类型,判断是访问数据/获取指令异常
根据具体异常原因编号找到对应的处理函数
检查并补全虚拟地址对应的各级页表,分配相应页框
根据可执行程序文件名从文件系统中把所缺的内容读入物理内存
不同文件系统、不同存储格式导致文件读取方式不同
设置该虚拟地址对应的PTE,使其指向存储缺页内容的页框
堆空间的请求调页
基本思想
malloc等函数申请内存时,可不立即分配物理内存
进程访问该页产生页错误时再分配内存并设置PTE建立映射关系
不涉及外存调入,只需在页错误发生时分配一个空闲页框
分类
匿名映射
不涉及外存文件的映射关系
对应的页:匿名页
文件映射
涉及外存文件的映射关系
对应的页:文件页
交换空间
目的
解决物理内存不足而又需要加载新的代码或数据
基本思想
将已装入内存的程序部分暂时换出到物理内存之外的某个存储空间,以空出页框
当再次访问到换出内存的程序部分时,再从外部存储空间将其调入内存
实现
交换空间被划分为与内存页大小相同的单元——块,每个块有块号
页换出
页错误处理分配页框失败
操作系统选择一个页换出到交换空间,记录块号,原PTE更新为swp_pte格式,记录交换空间信息
将数据写入交换空间,释放内存页
空出的页框分配给所需进程
页换入
访问一个已被换出的页,因PTE无效触发异常
根据PTE情况判断时请求调页还是从交换空间换入页
两种方式
同步内存回收
系统中无可供分配的空闲页框时在内存分配函数中同步调用页回收过程
异步内存回收
系统周期性检查,空闲页框数量低于某个阈值时,唤醒kswapd进程来主动回收页
页置换策略
三种策略
随机淘汰
先进先出FIFO
未区分分页重要性,存在陷阱现象
最近最久未使用策略LRU
基于程序的局部性原理
openeuler采用该策略
实现
为每个页设置访问标记,链表记录访问情况
5个链表
非活跃匿名页LRU
活跃匿名页LRU
非活跃文件页LRU
活跃文件页LRU
不可回收LRU
匿名页的回收
活跃匿名页LRU尾部数据移动到非活跃匿名页LRU头部
非活跃匿名页LRU尾部数据分类处理
近期访问过(PTE中AF为1)
移动到活跃匿名页LRU尾部,清零AF
近期未访问过(PTE中AF为0)
尝试回收
文件页的回收
流程与匿名页基本一致
标识位为PG_referenced,由文件操作代码显式地置位
收藏
收藏
0 条评论
下一页