内存管理之分页

昨晚读《go语言学习笔记》的时候,看到了内存管理这一章,提到了内存的分页。其实分段与分页在微机接口这课程也学过,只是一直在弄上层的东西,有点儿生疏了,今天有空查了点资料,做了点笔记。

虚拟地址与物理地址

首先假定平台为32位平台。

首先从应用层谈起,在应用层,我们有一个4G的完整的内存空间,我们可以通过对变量的寻址来读写某个变量,对于应用这一层来说,底层的内存管理的确是不可见的,而且对于应用层,也不需要考虑底层的内存到底是什么,只要可读可写就行了。

但是仔细想想,每个进程都有独立的4G的内存空间,那内存哪里够用呢,所以我们使用的这些地址,都属于虚拟地址(逻辑地址),而虚拟地址需要经过某些映射才能获取真正操作的内存,而映射的结果就是物理地址。

分页

上述谈到了某些映射,而分页机制就是属于映射过程中中很重要的一个概念。

刨除其它概念,分页其实也很简单,就是把内存分为4k大小的片,每一片成为一个分页,而我们的寻址,假设只需要寻址到某个页,那么其实只需要20字节。

想要隔离应用之间的内存空间,有很多做法,曾经也有在A程序时间片完成后,将其内存存入硬盘中,然后将程序B的硬盘中的内存内容恢复然后继续执行的做法,当然这么做在现在看来效率是非常低的。

为什么要做内存隔离呢?当程序和程序之间隔离了内存,那么程序无论执行什么,都不会影响别的程序,提高了稳定性,另一方面也不会影响到操作系统的内存空间,系统就会更加的稳定。

如今的内存隔离大部分都是通过一个程序分配一个页表的表,当然听起来有点儿绕,就是二级表,该表内存着的是页表的物理地址。

页表的表,通常占据一个分页,4k大小。其中每一项的大小为4字节,总共有1024项。而其中每个4字节存储的就是页表的物理地址。

上述谈到的存储的4字节物理地址,其实也不尽然,上面已经谈到了,对于分页的寻址,20字节就够了,还有12字节是标志位,可以设定权限控制等等。

页表的结构也差不多,1024项,每项4字节。

然后我们分析下逻辑地址。逻辑地址有32位,而逻辑地址映射到物理地址,就要用到上述谈到的分页表。

首先,逻辑地址是有格式的,高10位是一个索引,可以在上述提到的第一个表中查到页表的物理地址,然后通过这个物理地址,我们可以寻址到页表,4k大小,1024项。次高位的10位也是一个索引,我们可以在页表的1024项中找到对应的4字节内容,而这个内容就是分页的物理地址了,于是我们通过逻辑地址已经找到了分页,但是只是寻找到了这个分页而已,4k中我们可能只需要访问其中的一个字节。

于是我们可以发现我们只是使用了20位而已,还有12位呢,那么12位的可寻址数是多少?对了,就是4k,称作页内偏移。于是我们可以通过这个逻辑地址精确的寻址到任意字节的内存,这就是大概的逻辑地址到物理地址的转换。

虚拟内存

然而程序不可能每一个都会使用4G那么大量的内存,内存不够的情况下,我们往往需要引入虚拟内存。

操作系统常常会将一个程序不经常访问的部分,置换入虚拟内存,假设程序再次访问了这部分内存,那么会引起缺页中断。

当该中断发生时,操作系统会采取置换算法来将虚拟内存中的内容置换入内存区域,这样程序就能继续执行了。

共 0 条回复
暂时没有人回复哦,赶紧抢沙发
发表新回复

作者

sryan
today is a good day