内存管理:分段、分区、分页

内存要怎么用起来呢?存储程序的思想,把程序放入内存,程序在CPU中取指执行!

而用户程序有逻辑地址,实际的内存是物理地址,于是先有一个地址重定位的问题。

由于程序载入内存之后,睡眠了的话,还会被移入到磁盘,因此在运行时做重定位更好,这叫做地址翻译

程序编译好是不用做任何更改的,当要运行的时候,创建进程控制块PCB,这里面就有一个基址,再把PC置为初始地址,基址+逻辑地址=物理地址。

分段

把整个程序放进内存?

不,放入的是程序段、数据段等。

那么,现在的PCB要放每个段的基址,这就形成了一个段表

此时的寻址就是:段基址+段内偏移。

程序分成多个段,代码段、数据段,每个段在内存中找到空闲的地方,然后把基址记录在LDT中,LDT初始化之后就赋值给PCB,PC指针设置成初值,然后根据PC指针进行取指执行,在每次执行的时候,都查这个LDT表,根据表中的基址和程序中的地址,在这里找到物理地址,然后就可以使用起来内存了。

分区

对程序进行分段,但是怎么找到空闲的内存呢?

对内存进行分区,固定分区与可变分区,当一个段提出请求的时候,就根据首先匹配、最佳匹配、最差匹配等算法进行分配。

操作系统用空闲分区表和已分配分区表来管理内存资源。

但是分区总会造成内存碎片的问题。

分区是虚拟内存上的。

分页

把段请求打散行不行?这就把连续化为离散。

物理内存分页,每页比较小,最多浪费1页。

用户要分段,物理内存要分页。操作系统既支持段,又支持页。

这个时候的寻址呢?

每个进程得有自己的页表页号表示逻辑页,而页框号表示物理页。

于是,通过页号能找到物理页,通过页内偏移就找到物理地址了。

利用分区适配算法,在虚拟内存中找出一个空闲分区,放入段,然后将段分页,映射到物理地址。需要用段表记录虚拟内存区域的对应,用页表记录对应页所在物理地址。

快表

单独的分页还不行,因为页小了,页表就变大了。

  • 只放用到的页号行吗?但不连续的页号没法随机访问,查起来很慢。
  • 使用多级页表呢?就像增加目录一样,但每增加一级,就多了一次访存。

于是,我要是能记住最近访问的页就好了,快表就是用硬件根据页号一步找到页框号。那如果快表里面没有呢?就老老实实去多级页表找。

为什么快表可以?因为程序对地址的访问有局部性!(循环、顺序)

页的换入换出

为什么要换入换出?为了实现虚拟内存!

在用户眼里有4G空闲,实际却不是哦,也就是说用户眼里这样的大内存是换入换出实现的!

换入的核心:请求调页,没有这个页号,就赶紧去磁盘调页,需要中断机制。

换出的算法:FIFO、LRU。

swap 分区就是做这个事:换入、换出 = > 虚拟内存 = > 段页 = > 程序载入 => 进程

什么叫颠簸呢?不断地在磁盘和内存中换入换出,但CPU啥也执行不了。

comments powered by Disqus
相关文章
JWT 的应用场景思考

JWT 的应用场景思考 简述 JWT JWT,全称 JSON Web Token。是一种开放标准,用于在各方之间安全传递信息,它是以 Base64 编码 json 对象的 token 。基于 token 的权限验证,与传统的 Session 认证完全不同,它不需要服务端保持 Session 记录,连用户状态都不需要关心。一旦用户登录网站,服务器就会生成 token,之后客户端每次登录时在HTTP的头信息中带上 token 即可。

阅读更多
如何在多个编程语言间切换自如

Attention 要自由切换编程语言,必然要通过实践,编程语言之海浩瀚无边,本文会随着作者的实践而不断更新,敬请期待。 基本思路 熟悉各语言基本语法,怎么定义变量、函数、控制流等,这里有语法简介、数据结构等章节。 识别各语言的特性,为什么 Python 有元组等,也就是要知道语言的特性和高级用法等。 在熟悉基本语法时,要能搞清楚各编程语言怎么描述相同的功能的。 在识别语言特性时,要能搞清楚各编程语言处理方式上的设计哲学。

阅读更多
在电脑上安装 Openwrt 作为旁路网关

🤔场景 既然回家了,有了家用路由器,就希望各个设备能够不需要安装对应的软件而直接科学上网、屏蔽广告等。 但原来的路由器太小众,没人提供相应的固件,也就是说没法刷机。 后来,我看到有关旁路网关的介绍,觉得这可能是一种解决方案。

阅读更多