虚拟内存
首先,什么是虚拟内存呢?
回答这个问题要从另外一个问题入手,也就是为什么有虚拟内存这个概念,我们知道一个程序要被执行,就要将他全部放入内存中,这样cpu才能访问到,一般情况下我们的物理内存也就是插在主板上的条子,比如说我的物理内存是512M,我现在要执行一个大小为 1G 的程序,按照我们前面说的,要运行这个程序就需要把这个程序全部放入内存,但是现在我们的内存只有512M,很显然放不下,简单点说就是不能执行,为了让我们的程序能执行,很显然我们就要想办法构造一个大于1G或者更大的内存出来,将我们的程序全部放进去,然后执行,怎么来构造这个内存呢?大家想想,我们的硬件系统中能作为存储器并且有很大空间的就只有硬盘,因此我们在硬盘上找到一个足够大的空间再加上我们的物理内存就构造出了这个大于1G的内存,那么我们就把这个内存叫做虚拟内存。现在应该知道什么是虚拟内存了吧,也就是物理内存加上硬盘上的一部分空间,从我个人的观点看,其实构造虚拟内存的目的就只有一个,那就是为了运行比实际的物理内存更大的程序!
虚拟地址空间:
操作系统为每个进程都分配4GB的虚拟地址空间,在分配之初,这4GB 的虚拟地址空间是没有任何实际意义的,也就是说只有4GB范围内的地址,就好比我现在有100个盒子,而我给每个人分配100个盒子的编号0~~~99,你现在只有盒子的编号,而没有盒子,所以你不能往盒子里面放东西,所以0~99的盒子编号是没有实际意义的,要想往盒子里放东西,我们就要用我们的盒子去具体化这0~~99的编号,比如说现在想要编号80的盒子能放东西,那么我们就要找到一个盒子放到编号为80的地方,这样的话80号盒子就能放东西了;同理,我们的4GB地址空间也是一样,如果想要这4GB的地址上能放上代码或则数据,那我们就要让这4GB的地址对应某个实际的物理存储器,这个物理存储器可以是虚拟内存或则存储在硬盘上的可执行文件本身;
任何时候,计算机上都存在一个程序能够产生的地址集合,我们称之为地址范围。这个范围的大小由CPU的位数决定,例如一个32位的CPU,它的地址范围是 0~0xFFFFFFFF (4G),而对于一个64位的CPU,它的地址范围为0~0xFFFFFFFFFFFFFFFF (64T).这个范围就是我们的程序能够产生的地址范围,我们把这个地址范围称为虚拟地址空间,该空间中的某一个地址我们称之为虚拟地址。与虚拟地址空间和虚拟地址相对应的则是物理地址空间和物理地址,大多数时候我们的系统所具备的物理地址空间只是虚拟地址空间的一个子集。这里举一个最简单的例子直观地说明这两者,对于一台内存为256M的32bit x86主机来说,它的虚拟地址空间范围是0~0xFFFFFFFF(4G),而物理地址空间范围是 0x000000000~0x0FFFFFFF(256M)。
在没有使用虚拟存储器的机器上,虚拟地址被直接送到内存总线上,使具有相同地址的物理存储器被读写;而在使用了虚拟存储器的情况下,虚拟地址不是被直接送到内存地址总线上,而是送到存储器管理单元MMU,把虚拟地址映射为物理地址。
大多数使用虚拟存储器的系统都使用一种称为分页(paging)机制。虚拟地址空间划分成称为页(page)的单位,而相应的物理地址空间也被进行划分,单位是页桢(frame).页和页桢的大小必须相同。在这个例子中我们有一台可以生成32位地址的机器,它的虚拟地址范围从 0~0xFFFFFFFF(4G),而这台机器只有256M的物理地址,因此他可以运行4G的程序,但该程序不能一次性调入内存运行。这台机器必须有一个达到可以存放4G程序的外部存储器(例如磁盘或是FLASH),以保证程序片段在需要时可以被调用。在这个例子中,页的大小为4K,页桢大小与页相同—— 这点是必须保证的,因为内存和外围存储器之间的传输总是以页为单位的。对应4G的虚拟地址和256M的物理存储器,他们分别包含了1M个页和64K个页桢。
在linux0.11内核中给每个程序都划分了容量为64mb的虚拟内存空间(摘自Linux内核完全剖析—基于0.12内核)也就是说4gb的虚拟内存不是每个程序单独使用的,而是各个程序共享的
首先,什么是虚拟内存呢?
回答这个问题要从另外一个问题入手,也就是为什么有虚拟内存这个概念,我们知道一个程序要被执行,就要将他全部放入内存中,这样cpu才能访问到,一般情况下我们的物理内存也就是插在主板上的条子,比如说我的物理内存是512M,我现在要执行一个大小为 1G 的程序,按照我们前面说的,要运行这个程序就需要把这个程序全部放入内存,但是现在我们的内存只有512M,很显然放不下,简单点说就是不能执行,为了让我们的程序能执行,很显然我们就要想办法构造一个大于1G或者更大的内存出来,将我们的程序全部放进去,然后执行,怎么来构造这个内存呢?大家想想,我们的硬件系统中能作为存储器并且有很大空间的就只有硬盘,因此我们在硬盘上找到一个足够大的空间再加上我们的物理内存就构造出了这个大于1G的内存,那么我们就把这个内存叫做虚拟内存。现在应该知道什么是虚拟内存了吧,也就是物理内存加上硬盘上的一部分空间,从我个人的观点看,其实构造虚拟内存的目的就只有一个,那就是为了运行比实际的物理内存更大的程序!
虚拟地址空间:
操作系统为每个进程都分配4GB的虚拟地址空间,在分配之初,这4GB 的虚拟地址空间是没有任何实际意义的,也就是说只有4GB范围内的地址,就好比我现在有100个盒子,而我给每个人分配100个盒子的编号0~~~99,你现在只有盒子的编号,而没有盒子,所以你不能往盒子里面放东西,所以0~99的盒子编号是没有实际意义的,要想往盒子里放东西,我们就要用我们的盒子去具体化这0~~99的编号,比如说现在想要编号80的盒子能放东西,那么我们就要找到一个盒子放到编号为80的地方,这样的话80号盒子就能放东西了;同理,我们的4GB地址空间也是一样,如果想要这4GB的地址上能放上代码或则数据,那我们就要让这4GB的地址对应某个实际的物理存储器,这个物理存储器可以是虚拟内存或则存储在硬盘上的可执行文件本身;
任何时候,计算机上都存在一个程序能够产生的地址集合,我们称之为地址范围。这个范围的大小由CPU的位数决定,例如一个32位的CPU,它的地址范围是 0~0xFFFFFFFF (4G),而对于一个64位的CPU,它的地址范围为0~0xFFFFFFFFFFFFFFFF (64T).这个范围就是我们的程序能够产生的地址范围,我们把这个地址范围称为虚拟地址空间,该空间中的某一个地址我们称之为虚拟地址。与虚拟地址空间和虚拟地址相对应的则是物理地址空间和物理地址,大多数时候我们的系统所具备的物理地址空间只是虚拟地址空间的一个子集。这里举一个最简单的例子直观地说明这两者,对于一台内存为256M的32bit x86主机来说,它的虚拟地址空间范围是0~0xFFFFFFFF(4G),而物理地址空间范围是 0x000000000~0x0FFFFFFF(256M)。
在没有使用虚拟存储器的机器上,虚拟地址被直接送到内存总线上,使具有相同地址的物理存储器被读写;而在使用了虚拟存储器的情况下,虚拟地址不是被直接送到内存地址总线上,而是送到存储器管理单元MMU,把虚拟地址映射为物理地址。
大多数使用虚拟存储器的系统都使用一种称为分页(paging)机制。虚拟地址空间划分成称为页(page)的单位,而相应的物理地址空间也被进行划分,单位是页桢(frame).页和页桢的大小必须相同。在这个例子中我们有一台可以生成32位地址的机器,它的虚拟地址范围从 0~0xFFFFFFFF(4G),而这台机器只有256M的物理地址,因此他可以运行4G的程序,但该程序不能一次性调入内存运行。这台机器必须有一个达到可以存放4G程序的外部存储器(例如磁盘或是FLASH),以保证程序片段在需要时可以被调用。在这个例子中,页的大小为4K,页桢大小与页相同—— 这点是必须保证的,因为内存和外围存储器之间的传输总是以页为单位的。对应4G的虚拟地址和256M的物理存储器,他们分别包含了1M个页和64K个页桢。
在linux0.11内核中给每个程序都划分了容量为64mb的虚拟内存空间(摘自Linux内核完全剖析—基于0.12内核)也就是说4gb的虚拟内存不是每个程序单独使用的,而是各个程序共享的