物理内存和虚拟内存

1.概念

物理内存:真实的硬件设备(内存条)
虚拟内存:利用磁盘空间虚拟出的一块逻辑内存,用作虚拟内存的磁盘空间被称为交换空间(Swap Space)。(为了满足物理内存的不足而提出的策略)

在很久以前,还没有虚拟内存概念的时候,程序寻址用的都是物理地址,取决于CPU的地址线条数,32位平台的话 2^32也就是4G 。且每次开启一个进程都给4G的物理内存。很显然你内存小一点,这很快就分配完了,于是没有得到分配资源的进程就只能等待。

而后引入了虚拟内存极大解决了这方面的问题,一个进程运行时都会得到4G的虚拟内存。这个虚拟内存你可以认为,每个进程都认为自己拥有4G的空间,这只是每个进程认为的,但是实际上,在虚拟内存对应的物理内存上,可能只对应的一点点的物理内存,实际用了多少内存,就会对应多少物理内存。

2.使用过程

内核会将暂时不用的内存块信息写到交换空间,这样以来,物理内存得到了释放,这块内存就可以用于其它目的,当需要用到原始的内容时,这些信息会被重新从交换空间读入物理内存。

linux的内存管理采取的是分页存取机制,Linux系统会不时的进行页面交换操作,以保持尽可能多的空闲物理内存,即使并没有什么事情需要内存,Linux也会交换出暂时不用的内存页面。这可以避免等待交换所需的时间。而liunx 常用的交换算法,根据”最近最经常使用“算法,会将一些不经常使用的页面文件交换到虚拟内存。

有时我们会看到这么一个现象:linux物理内存还有很多,但是交换空间也使用了很多。其实,这并不奇怪,例如,一个占用很大内存的进程运行时,需要耗费很多内存资源,此时就会有一些不常用页面文件被交换到虚拟内存中,但后来这个占用很多内存资源的进程结束并释放了很多内存时,刚才被交换出去的页面文件并不会自动的交换进物理内存,除非有这个必要,那么此刻系统物理内存就会空闲很多,同时交换空间也在被使用,这是正常现象。

进程访问一个内存时过程:

  • 进程还没开始运行时, 磁盘中程序的文件和虚拟内存先建立好映射,此时数据还在磁盘中。并没有拷贝到物理内存
  • 当运行对应程序代码段的时候,之前虚拟内存建立的映射中,会有张页表项,记录实际的磁盘地址,和是否已经加载到物理内存中。
  • 当发现数据未加载到物理内存时,发生缺页异常,对应的缺页中断响应函数会将磁盘上的数据拷贝到物理内存中。
  • 而当对应的数据已经加载过时,会直接从物理内存获取。同时要是已经拷贝到物理内存的数据好久没用,liunx又会将不经常使用的页面文件交换到虚拟内存

虚拟内存与物理内存的联系
物理内存和虚拟内存_第1张图片

3.页表的工作原理如下图

物理内存和虚拟内存_第2张图片

  • 我们的cpu想访问虚拟地址所在的虚拟页(VP3),根据页表,找出页表中第三条的值.判断有效位。 如果有效位为1,DRMA缓存命中,根据物理页号,找到物理页当中的内容,返回。
  • 若有效位为0,参数缺页异常,调用内核缺页异常处理程序。内核通过页面置换算法选择一个页面作为被覆盖的页面,将该页的内容刷新到磁盘空间当中。然后把VP3映射的磁盘文件缓存到该物理页上面。然后页表中第三条,有效位变成1,第二部分存储上了可以对应物理内存页的地址的内容。
  • 缺页异常处理完毕后,返回中断前的指令,重新执行,此时缓存命中,执行1。
  • 将找到的内容映射到告诉的缓存当中,CPU从告诉的缓存中获取该值,结束。

总结

  • 物理内存是所有进程都可以访问的一块内存区域,物理内存又非常有限,因此liunx为了充分利用物理内存,只有当程序第一次执行到这块代码段时,根据分页表,缺页中断处理将数据拷贝到物理内存。
  • 当不同的进程使用同一段代码时,比如库文件的代码,在物理内存中可以只存储一份这样的代码,不同进程只要将自己的虚拟内存映射过去就好了,这样可以节省物理内存

本文部分转自该楼主虚拟内存与物理内存的联系与区别 的博客,有需要可参考

你可能感兴趣的:(UNIX,环境编程)