操作系统如何通过cpu的内存管理单元MMU把虚拟地址转变位物理地址
内存分段:将内存按功能属性划分为段。
内存分页
内存分段如何映射
段选择因子(段寄存器),段内偏移量。
分段的问题
内存碎片:
1.外部碎片:大量不连续的小内存2.内部碎片:不常用内存
用内存交换解决:将不常用的换出,将细小的换出整合再换入。
导致内存交换率低:
一旦交换,就是整个数据段交换,开销过大。
内存分页如何映射(为了解决内存交换开销过大)
1.先分页,再通过MMU页号,页内偏移,页表查询,是否缺页。
如何解决的:
以页为单位释放,只进行部分的换入换出。
简单分页缺点
存储信息开销过大:需要大量内存保存页表中每页的基地址
解决多级页表
多级页表原理
用时创建
段页式内存管理
第一次访问段表,得页表地址(用段代替多级页表)
访问页表,得页基地址
访问页基地址,加上编译量
linux内存管理
采用分页,又有分段
具体:每段起始位置一样,地址空间是线性地址空间,段只用于访问控制和内存保护。
代码段:二进制可执行代码。
malloc如何分配内存?
1.brk():系统调用移动堆顶指针,小于128k
2.mmap():系统调用;映射,大于128k
分配虚拟内存后,什么时候分配物理内存
分配的都是虚拟内存,分配后访问虚拟内存,触发缺页中断,操作系统建立虚拟内存到物理内存的映射。
malloc分配大小
malloc分配会多16字节保存分配空间信息,信息在free空间时起到确认大小作用
free释放会归还系统吗
brk()小于128k不会归还,缓存在malloc内存池,下次复用,节省申请与归还的时间开销。
free怎么知道释放多少?
malloc分配时,分配字节维护空间信息
brk()与mmap()
mmap()会频繁通过系统调用申请与释放空间,造成运行态到内核态切换的时间开销,发生缺页中断。
brk()因为是连续的,通过维护一个内存池,减少系统调用,与缺页中断发生的次数。
但容易造成不可检查的内存泄漏,:碎片化空间分配在内存池中,表面上已经free()导致不可检查。
虚拟内存有什么用
1.让每个进程都有自己的页表,进程之间相互独立
2.页表除了有物理地址,还有控制信息,如一个页的读写权限,标记页是否存在。
内存的分配过程是怎么样的?(延时分配)
应用程序一开始分配的都是虚拟内存,只有当cpu访问时,发现没有映射到物理内存,发生缺页中断,从用户态切换到内核态,调用内核中断函数处理。
中断函数是如何处理
1.有空闲,直接映射建立联系
2.没有空闲,进行内存回收。
内存回收
后台内存回收:唤醒内核线程,异步的回收,不阻塞,可以一边申请分配内存,一边回收
直接内存回收:异步回收跟不上申请时,阻塞进程,回收内存。
触发OOM机制:根据算法直接杀死一个内存占用较高的进程,回收其资源。
可回收内存
文件页(硬盘中已有的数据):1.没有修改2.修改过的脏数据
匿名页(从虚拟地址映射到内存中的):必须先通过swap机制把页换入磁盘,再释放。
swap机制
内存不够时,负责将不常用的内存临时保存到磁盘,当再次程序运行时,再从磁盘出恢复到内存中。
换出:换入:
利用swap分区可以分配大于物理内存的空间
可以分配超过物理内存,同时使用不能超过物理内存
用到虚拟内存时才将内存换入物理内存中
缺页中断与一般中断区别
1.缺页中断是异步,在指令执行期间,去处理中断信号。一般中断在指令执行完成后,处理中断信号。
2.缺页中断返回后重新回到原指令执行。一般中断回到下一条指令执行。
缺页中断处理过程
1.访问物理内存,是否缺页
2.操作系统接收缺页中断请求后,查找磁盘中页面的位置。
3.磁盘中找到页面后,寻找空闲页换入物理内存
4.将页表修改位有效
5.cpu重新执行指令,访问内存。
页表:(页号,物理页号,状态位,访问字段,修改位,磁盘地址);
页号:对应MMU。物理页号:物理内存地址
状态位:标记是否有效,在物理内存中?
访问字段:记录被访问次数,供置换算法选择页面
修改位:标记是否修改,有修改,先写入磁盘再释放
硬盘地址:指出该页在硬盘的地址
页面置换算法
最佳页面置换算法(OPT):置换 [在未来] 最长时间不访问的页面(计算下一次访问到来的时间)但实际中访问是动态的,无法计算
先进先出置换算法(FIFO):选择在内存中时间最久的置换
最近最久未使用的置换算法(LRU):置换最长时间不访问的页面:需要维护一个链表,每次访问页面,都有改变链表(头插)。
时钟页面置换算法(Lock):环形链表,通过访问位,寻找在内存中最长时间
最不常用置换算法(LFU):