内存分配与内存管理的一些理解

内存分配方式与内存分配算法算法

内存分配方式有两种,连续内存分配方式和离散内存分配方式。不一样的分配方式又有不一样的分配算法。ide

内存分配算法,其实就是:有一大块空闲的资源,如何合理地分配资源?内存分配的思想能够用到不少其余的领域。好比Java虚拟机是如何将内存分配与回收的?再好比文件系统是如何将磁盘块分配与回收的?其本质就是如何把空闲的资源分配出去,分配以后又如何回收?目标就是分配快,回收也快,并且还不浪费。那么,就须要根据资源的特色、以及应用场景作权衡从而选择何种方式进行分配与回收。spa

 

①连续内存分配方式进程

1)固定分区分配内存

将内存划分红若干个固定大小的块。将程序装入块中便可。内存划分红各个块以后,块大小再也不改变。固然,划分块的方式有:全部的块大小相等;划分的块大小不相等。资源

这种方式,在实际的内存分配以前,就已经知道了全部的内存块大小了。虚拟机

 

2)动态分区分配io

须要一个空闲表 或者 空闲链 来记录目前系统中空间的内存区域。在内存分配时,须要查找空间表或空闲链找到一块内存分配给当前进程。垃圾回收

 

动态分区分配算法:循环

a)首次适应法

b)循环首次适应法

c)最佳适应法

d)最坏适应法

e)快速适应法

 

3)可重定位分区分配

说白了,就是增长了内存移动的功能。因为若干次内存分配与回收以后,各个空闲的内存块不连续了。经过“重定位”,将已经分配的内存“紧凑”在一块(就相似于JVM垃圾回收中的复制算法)从而空出一大块空闲的内存出来。

”紧凑“是须要开销的,好比须要从新计算 地址,这也为何JVM垃圾回收会致使STW的缘由。

而离散分配方式--不论是分页仍是分段,都是直接将程序放到各个离散的页中。从而就不存在“紧凑”一说了。

 

连续内存分配方式涉及两种操做:内存分配操做 和 内存回收操做

 

②离散内存分配方式

内存资源是有限的,程序要运行,必须得加载到内存。若是内存已经满了,而如今又有新的程序要运行,怎么办?---SWAP

把当前不用的程序(数据)先换出内存,从而就有空间 加载当前须要运行的程序的一部分数据进入内存,这样大大提升了内存的利用率。

因为牵涉到换入与换出,前面的连续内存分配方式就有点不适用了。由于,最明显的一个问题:对于连续内存分配方式,究竟换出哪部分数据呢?

而这种只装入部分"数据"就可使程序运行的机制,就是虚拟存储器的本质。

 

1)分页存储管理

将进程的逻辑地址空间分红若干大小相等的页面;同时,也将物理内存分红相等大小的页面(称为块或frame)。在为进程分配内存时,以块为单位将进程的若干页 能够 装入到内存中多个不邻接的物理块中。

从上能够看出:“离散” 体如今:进程在内存中分配的空间(物理块)是不连续的。而对于连续分配方式,进程在内存的分配的空间是连续的。

如今考虑32位系统,每一个物理块的大小为4KB。如何把逻辑地址 转换成 物理地址?

对每一个进程而言,都有着本身的页表。页表的本质就是逻辑地址到物理地址的映射。

分页存储中的逻辑地址的结构以下:

1)因为进程的逻辑页面大小与物理块(页帧)大小相同,故都为4K,所以须要12个位表示4K的大小(2^12=4K),即图中的【0-11】

2)【12-31】表示的是页号。一共有20个位表示页号,也即:对于一个进程而言,一共能够有1M(2^20=1M)个页。

3)每一个进程的逻辑地址空间范围为0-2^32-1,由于:每一个页大小为4K,一共有1M个页。故进程可用的逻辑空间为2^32B

 

逻辑地址到物理地址的转换须要用到页表。具体细节是有一个“地址变换机构”,它有一个寄存器保存页表在内存的起始地址 以及 页表的长度

上面提到,一个进程最多能够有1M个页,故页表就有1M个页表项。假设每一个页表项只有1B,那页表的大小也有1MB,因此:通常而言,页表也是很大的,不能全放在寄存器中,故页表也是存储在内存中的。(有些机器有“快表”,快表就是一个寄存器,它保存了页表中的部分表项);其次,也可使用多级页表以解决单个页表太大的问题。

那如今给定一个逻辑地址,怎么知道其物理地址呢?

①将【12-31】位的页号与 页表的长度比较。页号不能大于页表长度,不然越界。

②根据页号 找到 该页号所在的页表项,即该页号对应着哪一个页表项。由于,页表项里面就存放着物理地址。

那如何查找页表项呢?将页号乘以页表项的长度(每一个页表项,其实就是一个逻辑的页 到 物理页 的映射信息),就知道了该逻辑页对应着哪一个页表项(根据页号匹配页表项通常是由硬件完成的)

而后,正如前面提到,页表也是保存在内存中的,故须要页表的内存始址(这是也为何地址变换机构 保存 页表在内存的起始地址的缘由),将页表始址 与 上面的乘积相加,就获得了该逻辑页对应的页表项的物理地址。读这个页表项的物理地址中的内容,就知道了该逻辑页对应的物理块地址(物理地址)。从而,就完成了逻辑地址到物理地址的转换。

从上面能够看出,CPU每存取一个数据时,须要两次访问主存。一次是访问页表项的物理地址,获得了数据的物理块地址。第二次拿着物理块地址去取数据。

在分页存储管理方式下:因为取一个数据,须要二次访存,CPU处理速度下降了一半,正因为这个缘由:引入了“快表”(又称TLB(Translation Lookaside Buffer)),快表是个寄存器,用来保存那些当前访问过的页表项。从而,读页表项时,不须要再访存了,而是直接从寄存器中读取。

 

虚拟存储器

谈到虚拟存储器,老是说它从逻辑上扩充了内存的容量,why?

内存是有限的,做业初始时保存在磁盘上的,若是要运行,必须得将相应的程序(数据)加载到内存中。那若是要运行的做业特别多,没法一会儿装入内存,怎么办?

一种方式是加内存条,这是从物理上扩充内存的容量。

另外一种方式是:先把做业的一部分程序(数据)装入内存,先让它运行着,运行过程当中发现: 咦,我还须要其余的数据,而这些数据还未装入内存,所以就产生中断(缺页中断)再将数据加载到内存。

采用这种方式,系统一次就能够将不少做业装入内存运行了。这时,从物理上看,内存仍是原来的大小,可是它能运行的做业多了,所以说从逻辑上扩充了内存。

将虚拟存储器这种思想与分页存储管理结合,一次只将做业的部分页面加载到内存中,造成了一个强大的内存分配与管理系统了。引入了虚拟存储器,一样须要有页表,记录逻辑地址到物理地址的映射,只不过此时的页表更复杂了,由于,有些页可能还在磁盘上。;还须要有缺页中断处理机构,由于毕竟只将一部分数据装入内存,会引发缺页中断嘛,就须要处理中断嘛;还须要地址变换机构,这里的地址变换机构功能更多,由于须要处理中断状况下的地址变换。

 

2)分段存储管理

与分页比较类似,不介绍了。

相关文章
相关标签/搜索