[翻译]虚拟内存介绍

原文地址 An introduction to virtual memory

计算机是用来执行简单任务的复杂机器:好比 上网、文本编辑、网页服务、视频游戏……,还能够对数据进行操做,图片 音乐 文本 数据库…… html

当计算机不使用的时候,程序和数据都安静地躺在磁盘里,即使你关机了数据也会在。运行一个应用就是让处理器(CPU)读取和执行程序代码的机器指令处理数据。 linux

磁盘能够保存大量的信息,但存取的时候都很是很是慢,比CPU慢得多,若是CPU直接从磁盘中读取指令,显然会成为整个系统的性能瓶颈。为此,主存/内存(RAM)就诞生了,内存是比磁盘小,但读写速度快得多的存储设备。应用运行时其程序和数据首先拷贝到内存中,这样处理器就能够在内存中读写数据,从而避免了大量的等待。 程序员

主存能够看做是一个很长的单元格列表,每一个单元格包含一些二进制数据,并用一个称为内存地址的数字进行标记。根据系统中可用的主存数量,内存地址的范围从0到N。程序使用的地址范围称为地址空间。 数据库

在这里插入图片描述

早期计算机的内存使用

在早期的计算机中(如今也见于某些嵌入式系统),程序是能够访问整个内存空间的,内存的管理也得由程序员本身实现。在这种类型的计算机上写程序是一种挑战,由于程序员得找到一种好的内存管理方式,以确保各程序之间内存不会覆盖和干扰。
问题在多任务的时候更复杂,由于程序员必须面对更严峻的问题?编程

  1. 内存布局 —— 当第一个程序分配走特定数目的内存空间后,可用内存初始范围将再也不是0-n了,开发者得妥善处理内存偏移。
  2. 内存分段。当内存被不断地分配回收以后,可用空间会逐渐变成愈来愈小的碎片,会愈来愈难以找到整块的空间分配给新的程序或者数据。
  3. 安全性。 若是程序A不当心覆盖了程序B的数据?或者有人故意从其余进程中读取敏感数据,好比密码和信用卡信息?

因此在1960年代初期,找到一种能自动管理内存方式尤其关键,这能够大幅度简化代码编写,并修复潜在的内存问题。最终诞生了咱们今天要说的虚拟内存浏览器

虚拟内存简介

在虚拟内存中程序并不直接访问物理内存,而是和虚拟内存地址空间交互。操做系统和处理器将虚拟内存地址转化为物理内存地址。 安全

进程每次的内存的读写都是在虚拟内存地址之上的,虚拟地址并不执行特定的物理地址,因此每次内存访问时程序并不知道硬件层面发生了什么。
在这里插入图片描述app

虚拟内存的优势

在上图中咱们能够看到虚拟地址和物理地址之间的映射关系,这种映射关系带来了两个好处。编程语言

  1. 每一个程序均可以有一个从0开始的虚拟内存地址空间,这大大简化了程序猿的编码,由于不须要再去手动维护内存地址的偏移了。
  2. 即使物理内存地址不连续但虚拟内存地址能够作到老是连续的,这样操做系统算是间接完成了将内存碎片合并成一块可用内存的艰巨工做。

虚拟内存机制也解决了内存有限的问题,由于操做系统能够给每一个进程分配比实际内存大的多的虚拟内存空间。另外虚拟内存也能够保证安全性,程序A没法在不触发操做系统错误的状况下读取到程序B的数据,下文中咱们将会介绍这一切是如何实现的。编辑器

分页

虚拟内存机制须要一个地方来存储虚拟地址和物理地址之间的映射关系,由于咱们须要将虚拟地址X转化为物理地址Y,固然你不能用1:1的映射,由于这样的映射关系数据将和实际内存同样大。

现代虚拟内存将多个固定大小的整块物理内存合并成一个列表管理,解决了上述映射关系过大的问题,这种实现方式就叫作分页。其中每一块在虚拟内存中叫页面在物理内存中叫页框,每个页面和页框是对应的。CPU的内存管理单元(MMU)以一种叫作页表的特殊数据结果存储这虚拟页框到物理页框的映射关系。页表比如是有个数据库,每一行都存储这页号+页框对应的物理内存地址。每一个进程在MMU中都会有本身的页表,以下图。
在这里插入图片描述

页表到页框的转化

虚拟内存地址由两部分组成

  1. 页号(页索引),标识这个虚拟内存地址属于哪一个页面。
  2. 页内偏移,标识这个地址在页框中的具体位置。

这些信息足够MMU将一个虚拟地址转化为物理地址了。当一个进程读写一个虚拟地址时,它先唤醒MMU从虚拟地址中截取出页号并根据页表找到相应的页框,当页框根据页内偏移计算出实际的物理地址,到这里转化就完成了。这时候程序就有了一个实际可读写的物理内存地址。

虚拟内存的背后

当程序有了连续、整洁的虚拟内存空间后,操做系统和硬件在后台对物理内存作一些很疯狂的事了。
例如:操做系统的延时加载,数据并非在程序开始运行前就加载数据,而是等到程序实际须要使用时才加载。全部你会发现有些时候可能某个程序的页面对应一些不存在的页框或者是尚未分配的页框。好比上图中的最后两个页面就没有指向任何页框。

像这样的取巧的手段对应用程序是彻底透明的,它保持读取和写入本身的虚拟地址空间而不受背景噪音的影响。可是,程序早晚要访问一个没有映射到RAM的虚拟地址:该怎么办

缺页错误(中断)

缺页中断发生于当程序尝试去访问一个没有映射到物理页框的虚拟地址时。更准确地讲,缺页中断发生于程序访问一个虚拟内存地址存在但在物理内存中没有对应地址的状况。

当MMU检测到缺页中断后会将中断信息转交给操做系统,操做系统会尝试去找到虚拟地址到物理地址的映射,大多数状况下这个是一个很简单的操做,除非物理内存已经耗尽。

分页,当物理内存不足时如何实现?

分页也带来一个其余的好处。当物理内存不足时,操做系统能够把部分页面写入到磁盘中腾出空间。尽管不够百分百准确,但这种方法有时也叫作swapping(交换),Swapping实际上是把整个进程都挪到磁盘中,固然如今有些操做系统在必要的时候也会这么作。

分页给了程序一种有无限可用内存的假象。操做系统乐观地容许一个比物理内存更大的虚拟内存地址空间,由于在须要的状况下数据能够被换进和换出硬盘。有些系统(例如Windows)会使用一个称为分页文件的特殊文件来达到这个目的。其余操做系统(例如Linux)有一个专用的硬盘分区,称为交换分区(因为历史缘由,现代Linux执行分页而不是交换)。

抖动

当操做系统花更多的数据在执行分页而不是应用程序的时候就会发生抖动,通常是由一系列的缺页中断致使的。这种状况极易发生在当你运行大量超过物理内存大小的程序时或者硬盘交换分区没有作优化时。这时候操做系统会努力执行大量的缺页中断,持续把数据从硬盘中移动到物理内存中,最终可能让系统卡住。解决方法是加大内存或者减小进程数量或者调整交换分区大小。

内存保护

虚拟内存也提供了跨进程的安全性。你的浏览器没法在不侵入操做系统的状况下窥探你文本编辑器里的内容,由于它没法访问不属于本身的内存空间。
内存保护机制是由MMU和其管理的页表实现的,也许其余硬件有不一样的实现策略。当程序试图访问不属于它的虚拟内存时,会触发invalid page 错误。MMU和操做系统捕捉到这个信号,并引起一个名为段错误(segmentation fault)(Unix)或无效访问(access violation)(Windows),操做系统而后就会直接杀死这个进程。

段错误和无效访问可能会程序错误而产生。可以手动管理内存的编程语言容许你本身管理一部份内存用来存储程序数据,操做系统会给你划分出一段空闲内存(又名缓冲区),以便根据你的程序须要进行读写。可是,没有什么能够阻止你在缓冲区边界以外读写,访问不属于您的程序或根本不存在的内存时,操做系统就会报出非法访问的信号。

更多内容

虚拟内存的技术为不少有趣的课题铺平了道路,好比内存文件就颠覆了传统的文件读取方式,传统的文件读取方式是把文件拷贝到内存里,取而代以内存映射的方式是把整个文件都加载到内存后直接在内存里操做。在必要时,虚拟内存机制将像往常同样负责将数据从硬盘驱动器移动到RAM。内存映射文件简化了程序员的工做也加快文件访问。更多信息参考这里

虚拟内存也让统计内存消耗变得更加困难。假设你的一个程序占用了300m的内存:它是虚拟的仍是物理的?该空间的一部分是否分页到磁盘?若是是,分页操做是否足够快?此外,若是您想使系统处于良好状态,那么调优分页文件/交换区域是一个重要的步骤。操做系统提供了许多度量和调整内存的工具:点击这里查看。

参考资料

Computer Hope — Memory
Peter J. Denning — Before memory was virtual
Android Authority — What is virtual memory?
Kernel.org — Memory Management
Operating Systems: Three Easy Pieces — Chapter 18: Paging
Philippe's Oppermann — Introduction to Paging
Computer Science from the Bottom Up — Chapter 6. Virtual Memory
Dr. John T. Bell — Operating systems, Virtual Memory
StackOverflow — Do modern OS's use paging and segmentation?
StackOverflow — What is thrashing? Why does it occur?
Wikipedia — Memory address
Wikipedia — Paging
Wikipedia — Address space
Wikipedia — Virtual memory
Wikipedia — Virtual address space
Wikipedia — Thrashing
Wikipedia — Segmentation fault
ITPro Today — Paging Performance
Aleph One — Smashing The Stack For Fun And Profit

相关文章
相关标签/搜索