你听说过虚拟内存的概念吗???
这是百度百科上的描述,说的很精辟,但是想必如果是一个新手,就会完全不知道所云。那虚拟内存到底是怎样一种技术呢?他的用处是什么呢?它为何而出现呢????
物理内存
假如我们没有虚拟内存的概念,只有物理内存。那你想象一下,我们现在使用计算机都是多核处理,多并发的,也就是说在同一时刻可能会有多个进程在同时运行,也就是说有限的物理内存需要分配给正在跑的所有进程。这会带来什么呢???
- 地址空间不隔离,所有程序都直接访问物理内存,地址空间不隔离,恶意的程序软件可以很容易的改写其他程序的内存资源,有些非恶意的,也可能不小心的修改了别的程序的数据,就会使其他程序崩溃,这对于需要安全稳定的计算环境的用户来说是不可容忍的。
- 程序运行地址的不确定性, 程序每次装入运行时,我们都需要给它从内存中分配一块足够大的空闲区域,这个空闲区域的位置是不确定的。程序访问数据与指令跳转时目标地址很多都是固定的。
- 内存使用效率低, 假设我们的计算机有128MB内存,程序A运行需要10MB,程序B需要100MB,程序C需要20MB,现在我们同时运行A和B,比较直接的做法就是将内存的前10MB分配给A,10MB~110MB分配给B,如果突然要运行程序C,这时候的内存空间已经不够了,只能将其他程序的数据暂时写到磁盘里面,等到用的时候在读出来。由于程序所需要的空间是连续的,那么在这个例子里面,如果我们将程序A的数据换出到磁盘里面所释放的内存空间是不够的,所以只能将B也换出来,然后将程序C装入到内存中开始运行。可以看出,由于没有有效的内存管理机制,整个过程有大量的数据换入换出,导致效率十分底下。
抽象
那么,面对这些问题,是怎么解决的呢,增加中间层,即使用一种间接的地址访问方法。整个想法是这样的,我们把程序给出的地址看作是一种虚拟地址 , 然后通过某些映射的方法,将这个虚拟地址转换成实际的物理地址。这样,只要我们能妥善地控制这个虚拟地址到物理地址的映射过程,就可以保证任意一个程序所能够访问的物理内存区域跟另外一个程序相互不重叠,以达到地址空间隔离的效果。
分段
最开始人们想到的是一种叫分段的方法,把程序所需要的内存空间大小的虚拟空间映射到某个地址空间。分段解决了前两个问题:
- 首先,如果程序访问了不是自己映射的地址,那么硬件就会认为这是一个非法的访问,拒绝这个地址请求,并将这个请求报告给操作系统或监控程序,由它来决定如何处理,解决了地址空间不隔离的问题。
- 再者,对于每个程序来说,无论他们被分配到物理地址的哪一个区域,对于程序来说都是透明的,他们不用关心物理地址的变化,解决了程序运行地址不确定的问题。
但是,这并没有解决第三个问题,内存使用效率低的问题。分段对内存区域的映射还是按照程序为单位的,如果内存不足,被换入换出的都是整个程序,这样势必会造成大量的磁盘访问,从而严重影响速度,这种方法还是显粗糙,颗粒度较大。
事实上,根据程序局部性原理,当一个程序运行时,在某个时间段内,只有一小部分数据能够频繁地被用到,人们自然想到了更小颗粒度的内存分割和映射的方法,分页.
分页
分页的基本方法是把地址空间人为地等分成固定大小的页,每一页的大小有硬件决定,或硬件多种大小的页,由操作系统选择决定页的大小。当我们把进程的虚拟地址空间按页分割,把常用的数据和代码页装载到内存中,把不常用的代码和数据保存到磁盘中,当用到时候把他从磁盘中去来即可。
这篇主要希望读者看完之后对虚拟内存有一个宏观上的认识,能知道为什么要有虚拟内存。
之后会有博客来讲虚拟内存的运行过程及原理实现。