一、内存管理简介
内存是计算机非常重要的资源,在通用的计算机存储结构里通常有cpu - 缓存 - 主存三层结构,而操作系统的内存管理主要负责的就是内存的分配与回收,因为Java依靠着虚拟机有着自动分配与回收,但是在C/C++中有着malloc分配函数和free内存释放函数。
另外在早期的内存管理是没有内存抽象的,也就是程序直接访问和操作的都是物理内存,这样导致任何程序都能访问内存,运行多个程序比较难,到后面有了地址抽象,而内存管理就需要将逻辑地址转为物理地址
二、常见的内存管理机制
常见的内存管理方式有连续分配管理方式和非连续分配管理方式,连续管理是指为一个用户程序分配一个连续的内存空间,连续管理分配方式又有单一连续分配、固定分区分配也就是块式管理等等,而连续分配会产生很多的碎片,于是乎出现了非连续分配管理比如说页式管理、段式管理和段页式管理
块式管理(连续)
:将内存分为一块一块,如果程序需要使用内存操作系统就分配一块给它,如果运行的程序都很小的话,分配的内存中很大一部分空间浪费了,也就是很容易产生碎片页式管理
:把主存分为大小相等且固定的一页一页的形式,页比较小,然后将程序进程也分为一片一片的逻辑地址空间成为页面,然后通过页表将程序的页面号对应主存中的真正物理地址段式管理
:页式管理按照页(固定大小)来管理内存,而段式管理是按照程序代码的内容或者过程函数划分为一个一个段,然后通过地址映射机构将虚拟地址转为实际的内存物理地址段页式管理
:段页式管理集中类段式和页式的优点,简单来说就是先将程序分为段,然后每一段又细分为一页一页,这样就更加提高了内存的利用率
分页与分段的同与异:
- 分页机制和分段机制都是为了提高内存利用率,减少碎片,都是使用离散分配的方式所以都需要维护一个地址转换机制
- 页的大小是固定的,而段是不固定的,分页仅是满足了操作系统内存管理的需要,由于分段是按照程序代码进行分段则更好体现程序的逻辑,满足用户的需要
三、快表与多级页表
在分配内存管理的时候,有很重要的两点:
- 从虚拟地址到物理地址的变换要快
- 页表(存虚拟地址与逻辑地址的映射表)可能会很大,也很占用空间
而快表与多级页表则分别解决上面两个问题
快表
页表是存在内存的,这就让CPU在存取数据的时候需要经过两次内存:
- 从内存中的页表中取出对应存取数据的物理地址
- 真正的从物理地址存取数据
这就导致CPU的处理速度降低1/2,为了提高地址变换速度,提出了快表,在CPU内部的高速缓冲里面增设一个快表项,其内容和页表中的内容是一样的,这就则CPU查找对应数据的物理地址可直接在CPU内部进行,速度将会大幅度增加,下面是有了快表之后的CPU地址变换的过程:
- 根据虚拟地址的页号在快表中查找物理地址
- 若命中,直接从快表中取出物理地址
- 若不命中,就访问内存中的页表,同时需要将该页表项写回到CPU中的快表中
其实快表就是我们经常使用的缓存策略
多级页表
多级页表就是防止全部页表项放在同一张页表上导致页表占用的内存过高的问题,多级页表是典型的空间换时间
四、CPU寻址方式
指令:操作码 操作数
8088/8086CPU一共有七种寻址方式:
-
立即寻址
:操作数在内存中的地址直接存放在指令中,紧跟操作码之后,作为指令的一部分存放在代码中,例如MOV AL,66H -
直接寻址
:操作数在内存中的地址由操作数地址的16位偏移量加上段基址mov ax,[4000h] -
寄存器寻址
:操作数在内存中的地址是寄存器中的内容,需要从寄存器中取操作数 mov ax, bx -
寄存器间接寻址
:操作数在内存中的地址是寄存器的偏移地址加上基址组成mov ax, [bx] -
寄存器相对寻址
:操作数在内存中的地址由寄存器的内容加上给出的一个偏移量组成 -
基址-变址寻址
:操作数在内存中的地址是由一个基址寄存器的内容和一个变址寄存器的内容和基址加
五、虚拟内存技术
一部20G的游戏却可以运行在8G的电脑上,其中使用到的原理就是虚拟内存技术,虚拟内存技术在程序运行中不用或者暂时不用的数据先不加载到内存中,等到需要使用的时候在进行加载,而局部性原理是虚拟内存技术的基础
时间局部性
:如果程序中的某条指令一旦执行,不久以后该指令可能再次执行,如果某数据被访问,不久以后该数据可能再次被访问空间局部性
:一旦程序访问了某个内存单元,在不久之后某附近的存储单元也会被访问
虚拟内存技术是建立在离散内存管理机制上的,根据离散内存管理的三种方式:页式管理、段式管理、段页式管理,虚拟机内存技术也分别有三种,重点说一说请求页式管理
请求页式管理
:建立在分页的基础上,为了支持虚拟内存技术额外增加了请求调页和页面置换的功能。请求分页是目前最常用的一种实现虚拟存储的方法,请求分页存储管理在作业运行之前,仅把装入当前需要的页,假如在程序运行过程中发现需要的页不在内存中,将会产生一个请求中断,则CPU采用页面置换算法将相应的页调入至内存中,同时也把不需要的页调出至内存中
六、页面置换算法
因为虚拟内存技术只是将部分当前需要的页调入内存中,但是如果在程序运行期间,所要访问的页面不在内存中,但是内存已无可用的空间的时候,就需要将需要的页面调入,不需要的页面调出,于是就有了下面的页面置换算法
最佳置换算法
:首先这是一个理想的算法,最佳置换算法淘汰的是后面永远不使用或者在最长时间内不再访问的页面,但是CPU是无法预测那个页面是未来最长时间不使用的,所以这个算法只是一个理想算法先进先出算法
:这是一个简单的算法,总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面进行淘汰最近最久未使用算法(LRU)
:最佳置换算法是判断最近的未来,而最近最久未使用算法是判断最近的过去,LRU算法要为每一个页面记录自上次被访问以来所经历的时间T,当需要淘汰页面时,选择淘汰T值最大的