您的位置:首页 > 职场人生

腾讯实习生面试--内存管理方法

2017-07-12 09:31 176 查看
由于腾讯实习生面试的比较早,具体问题我也给忘了。但是我记得是一个关于操作系统内存分配方案的,当时关于操作系统之类的知识大部分都忘了。今天在这里对操作系统中内存管理这一块做一个总结。

1、内存管理的背景:

当前的计算机都是支持多个进程并行执行的,多个进程在单核CPU上以时间片为单位不断的轮换执行。通常情况下,多个进程并发执行所需要的ROM数目要远远超过计算机的实际内存的。那么CPU是如何做到所需的ROM数超过内存时,仍能够正常运行呢?这就需要高效的内存管理技术。

也许是受“CPU在不同进程之间以时间片为单位高速切换来处理多个任务”这种方法的启发,将这一原理应用到内存管理方面。

2、方法

现有两种内存超载的处理方法:交换和虚拟内存。下面我们针对这两种方法分别进行详细说明。

2.1 交换

(1)什么是交换技术?

把一个将要运行的进程(process)调入内存中运行一段时间后,再将其调出到本地磁盘。空闲进程主要都在本地磁盘中存放着,所以不运行的进程不会耗费计算机的内存资源。(将要运行进程调入内存中,运行一段时候在调回到磁盘中)。

(2)进程交换的例子



上图是一个进程之间内存交换的例子。图(a)中,橙色部分为内存中空闲部分。在图(b)中,显示当一个进程a被调入内存中进行运行时的状态。图(c)(d)显示的是进程b、进程c调入内存中,内存的状态。此时内存中共放了3个进程。当时如果想要放入进程d时,显然剩余的空闲内存已经不够了。此时需要使用某个替换策略将某块内存换出,换入。

注意:刚开始时进程a在内存中运行一段时间后被换出到本地磁盘,等一会a又被掉入内存。这两次中a在内存中的位置时不同的,需要使用“重定位”技术才能够保证a接着从上次停止的地方继续往下运行。重定位技术要使用到两个部件为“基址寄存器”和“界限寄存器”。

(3)内存紧缩技术

从最后一个图(d)我们可以看到,内存中有两个不连续的小空闲区,这种情况下无法在两个小的空闲去运行一个进程,但是如果将这两个小的空闲区连成一个大的空闲区就可以运行一个进程了。

将多个小的空闲区下移到放在一起构成一个大的空闲区,这种技术叫作“内存紧缩技术”。

(4)一个进程的内存布局

在第二部分我们讨论了多个进程在内存中的交换方式和布局,在这里我们对一个进程在内存中的情况进行讨论。一个进程在执行过程中所占用的内存可能会增加,因为会有新数据产生,新内存的申请。因此,一个进程除了进程的程序所占的空间之外还要额外的空间来存储进程运行过程中产生的数据。

所以所一个进程所占的内存应该包括:堆区、栈区、全局/静态数据区、常量区、代码区。

Q:堆和栈上变量的区别表现在这几方面:内存管理方式不同、内存增长方式的不同、碎片的区别、效率的不同

(5)空闲内存的管理方法(用于显示当前内存的布局)

位图法:内存中每个存储单位对应着位图中的一个二进制位,如果这个存储单元被占用,位图中为1;如果这个存储单元不被占用,位图中为0;

位图的大小由总内存大小、每个存储单元大小共同决定。

链表法:将一段连续的空闲区或者已分配区存放在链表的一个节点中。

struct LinkNode
{
int startAddr;//起始地址
int n;//所占字节数
bool f;//标记空闲区或者被分配区
LinkNode *next;//下一个节点的指针
};
使用LinkNode将当前进程所占用的内存和空闲内存穿起来形成一个链表。

当新的进程来时,需要使用一定的内存分配策略给新进程分配内存。现有的内存分配策略有:

首次适配:每次都从链表头部开始找一个能够装得下进程的空闲区;

下次适配:从上次结束的位置开始(不是每次从头开始),找到能够放得下进程的空闲区;

最佳适配:遍历整个链表,找到一个恰好能够放得下进程的空闲区;

最差适配:遍历整个链表,将链表中最大空闲区分配给进程。如果没有空闲区满足,使用交换技术换出一个进程。

2.2 虚拟内存

在交换技术中用到的“重定位技术”是指:进程a在内存中执行一段时间后被换出到本地磁盘,一段时间后a又被调入内存,为了使进程a接着上次的位置继续执行,要对a进行“重定位”。

(1)为什么需要虚拟内存

交换技术是指将整个进程换入换出到磁盘,整个进程都需要在内存中才能够执行。但是现实中,一个程序所需要的内存就可能大于物理内存,无法将整个程序都放入内存中,这时就需要“虚拟内存”技术。

(2)什么是虚拟内存

虚拟内存的实现需要两个手段“需要时加载”和“换入换出”。所谓“需要时加载”就是一个程序运行时,不需要将程序的所有数据都装入物理内存中,只要将程序运行所需要的那部分放入内存中即可。从而可以运行所需内存比物理内存大的程序。当然实现虚拟内存还需要其他额外的技术。

所谓“换入换出”是指,当物理内存满时,要将物理内存中不使用的页面换出,然后将要运行的换入物理内存。

(3)分页

1>逻辑地址到物理地址映射

虚拟地址空间大小:虚拟地址有nbit,那么虚拟地址空间大小为2^nbit;

一个页面的大小:一个内存单元大小,k bit,则一个页面大小为为2^k bit;

页号:逻辑地址中每个页面会对应着一个页号;

页框号:将物理地址中每个单元进行编号,一个物理内存单元对应着一个页框号;

页表:页号到页框号的映射;如果一个页号对应的页框号不存在,就会引发缺页中断。

那么这个程序可以分为2^n / 2 ^k 个页面。

程序首先在虚拟内存中存放着,如果程序执行过程中需要某个页面的话,首先会通过MMU看这一个页面在不在物理内存中。如果在物理内存中,直接运行;如果通过MMU映射后发现不在物理内存中,产生缺页中断,需要将其调入内存中。调入之前会使用页面置换算法将物理内存中某个页面换出,将要执行的放入物理内存中。

MMU(内存管理单元):MMU是内存管理单元,用于实现从虚拟空间的一个逻辑地址到物理内存中地址的映射;(ARP:IP地址---->MAC地址)

例子:

如果程序执行过程中需要执行逻辑地址a的那段程序,系统会通过MMU将逻辑地址a映射到物理内存中的一个物理地址b。如果映射成功,说明a已经被装入内存,直接运行即可;如果发现a没有被放入内存中,就会产生缺页中断,调用页面置换算法清除物理内存中的一个位置,并把a放入内存中并建立映射。

MMU中过程:逻辑地址a------>物理地址b

方法一:a/(2^k)是逻辑地址的页号,a%(2^k)是页面内的偏移。在页表中使用页号找到对应的页框号,在于页内偏移连接起来就是物理内存的地址。b = f(a/(2^k)) * 2^k + a%(2^k),其中f为页表的映射。

方法二:将a用二进制表示,高n-k位就是页号对应的二进制,低k位是在该页面中的偏移。在页表中根据页号查找到对应的页框号,然后使用页框号替换a中的高n-k位就是内存中的物理地址b。如果页表中页号对应的页框号不存在,引发缺页中断。



注意:可以使用快表、多级页表等策略加速逻辑地址到物理地址的映射;

每个逻辑地址分为页号,页内偏移。在页表中根据页号找到页框号。

2> 页面置换算法

当想要使用某段程序时,MMU发现改程序不在物理内存中,此时引发缺页中断。系统会用某种策略从当前内存中去除一个,然后将其调入物理内存中。这时就需要页面置换算法。

FIFO:将最早放入物理内存中的页面换出去;

LRU:将最近未使用时间最长的页面置换出去;

(4)分段

Q:何为分段?

A:分页中整个程序的逻辑地址是连续的(从0开始,线性增长,一直到程序结束),一个地址接着另一个地址。使用分页的虚拟地址是一维的,每个页面大小是固定的。

对于分段而言,将整个程序分为若干个段,每个段的大小是不同的。每个段是一个独立的逻辑地址空间,每个段都是从0开始的线性地址,段与段之间互不影响。



上图中我们将一个进程分为4个段,每个段大小都是不同的,每个段起始地址都是从0开始的。

Q:纯分段的内存管理

A:类似于分页内存管理,纯分段内存管理是指程序运行时,会将整个段都装入到内存中,这种方法显然是抵消的。

Q:段页式内存管理

A:在分段的基础上,对每个段进行分页。每个逻辑地址分为三部分:段号,段内页号,页内偏移。

首先根据段号去找对应的页表,如果没有找到这个页表,产生一个段错误;如果找到,在页表中根据页号去找页框号,然后在结合页内偏移获得物理地址。如果页表中对应的页号不存在,产生缺页中断。

Q:段页式存储管理地址映射过程

A:

(1)程序执行时,从PCB中取出段表始址和段表长度,装入段表寄存器。
(2)由地址变换机构将逻辑地址自动分成段号、页号和页内地址。
(3)将段号与段表长度进行比较,若段号大于或等于段表长度,则表示本次访问的地址已超越进程的地址空间,产生越界中断。
(4)将段表始址与段号和段表项长度的乘积相加,便得到该段表项在段表中的位置。
(5)取出段描述子得到该段的页表始址和页表长度。
(6)将页号与页表长度进行比较,若页号大于或等于页表长度,则表示本次访问的地址已超越进程的地址空间,产生越界中断。
(7)将页表始址与页号和页表项长度的乘积相加,便得到该页表项在页表中的位置。
(8)取出页描述子得到该页的物理块号。
(9)对该页的存取控制进行检查。
(10)将物理块号送入物理地址寄存器中,再将有效地址寄存器中的页内地址直接送入物理地址寄存器的块内地址字段中,拼接得到实际的物理地址。

(5)分段与分页有什么区别?

原理:分页是一维的,将整个程序看做一个整体,地址从0开始线性增长。每个部分都有一个地址,地址与地址之间是连续的。程序被放在若干大小相同的页中,每个页面的大小是相同的。

分段是二维的,是将整个程序分为若干个段,每个段的地址都是从0开始的,每个段的大小是不同的。段页式内存管理中,会在对每个段进行分页。

(1)页是信息的物理单位,分页是为了实现非连续分配,以便解决内存碎片问题,或者说分页是由于系统管理的需要.段是信息的逻辑单位,它含有一组意义相对完整的信息,分段的目的是为了更好地实现共享,满足用户的需要;

(2)页的大小固定,是由系统确定的,将逻辑地址划分为页号和页内地址是由机器硬件实现的。而段的长度不是固定的,决定于用户的程序长度,通常由编译程序进行编译时根据信息的性质来划分;

(3)分页式存储管理的作业地址空间是一维的,分段式存储管理的作业管理地址空间是二维的;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: