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