虚拟内存和物理内存有什么区别?

140

我经常对操作系统中的虚拟化概念感到困惑。将RAM视为物理内存,为什么我们需要虚拟内存来执行进程?

当从外部硬盘驱动器中获取进程(程序)并放入主内存(物理内存)以进行执行时,虚拟内存位于哪里。

谁负责虚拟内存,虚拟内存的大小是多少?

假设RAM大小为4GB(即2^32-1地址空间),虚拟内存的大小是多少?


4
如果你只有512MB内存,但需要寻址4GB,该怎么办? - Oded
只有所需程序部分被加载到主内存中。如果我有错误,请纠正我。谢谢。 - starkk92
5
虚拟内存就像盲人摸象一样,每个人都会有不同的印象。 - Hot Licks
DOS相关的TSR程序:https://en.m.wikipedia.org/wiki/Terminate_and_stay_resident_program - EsmaeelE
6个回答

173
软件在操作系统上运行的前提非常简单 - 它们需要内存。设备操作系统以 RAM 的形式提供它。所需内存量可能会有所不同 - 一些软件需要大量内存,而一些则需要很少的内存。大多数(如果不是全部)用户同时在操作系统上运行多个应用程序,并且鉴于内存昂贵(且设备大小有限),可用内存量始终受限。因此,考虑到所有软件都需要一定数量的 RAM,并且所有软件都可以同时运行,操作系统必须注意以下两点:
1. 软件始终运行直到用户中止它,即它不应因为操作系统已经耗尽内存而自动中止。 2. 在维护正在运行的软件的良好性能的同时,完成上述活动。
现在,主要问题归结为如何管理内存。究竟是什么决定了属于给定软件的数据将存在内存的哪个位置?
可能的解决方案 1:让各个软件明确指定它们将在设备中使用的内存地址。假设 Photoshop 声明它将始终使用从 0 到 1023 的内存地址范围(将内存想象成字节的线性数组,因此第一个字节位于位置 0,第 1024 个字节位于位置 1023) - 即占用 1 GB 内存。类似地,VLC 声明它将占用内存范围 1244 到 1876,等等。
优点:
  1. 每个应用程序都预先分配了一个内存槽,因此当它安装和执行时,它只是将其数据存储在该内存区域中,一切正常。

缺点:

  1. 这不具有可扩展性。理论上,当应用程序执行某些重度任务时,可能需要大量内存。因此,为了确保它永远不会耗尽内存,分配给它的内存区域必须始终大于或等于所需内存量。如果一款软件的最大理论内存使用量为2 GB(因此需要从RAM分配2 GB内存),而安装在只有1 GB内存的机器上,该怎么办?软件是否应该在启动时中止,并表示可用RAM小于2 GB?还是应该继续运行,当所需内存超过2 GB时,立即中止并以“内存不足”的消息退出?

  2. 无法防止内存混乱。有数百万种软件,即使每个软件只被分配1 kB内存,所需总内存也将超过16 GB,这比大多数设备提供的内存还要多。那么,如何分配不会侵犯彼此区域的内存槽?首先,没有集中的软件市场可以调节新软件发布时必须从“尚未占用的区域”分配多少内存,其次,即使有,也不可能做到这一点,因为软件数量实际上是无限的(因此需要无限的内存来容纳所有软件),任何设备上可用的总RAM都不足以容纳所需的一小部分,因此必然会导致一个软件的内存边界侵犯另一个软件的内存边界。那么当Photoshop被分配内存位置11023,而VLC被分配10001676时会发生什么?如果Photoshop在位置1008存储了一些数据,然后VLC用自己的数据覆盖了它,稍后Photoshop访问它,认为它是先前存储在那里的相同数据,你可以想象,会发生糟糕的事情。

很明显,正如你所看到的,这个想法相当天真。

可能的解决方案2:让我们尝试另一个方案 - 让操作系统大部分管理内存。软件只需在需要任何内存时向操作系统请求,操作系统将相应地进行调整。例如,如果新进程请求内存,操作系统将确保从可能的最低字节地址(如前所述,RAM可以想象为字节数组,因此对于4 GB RAM,字节的地址范围为0到2 ^ 32-1)分配内存,否则,如果是正在运行的进程请求内存,则将从该进程仍然驻留的最后一个内存位置分配。由于软件将发出地址而不考虑实际存储数据的内存地址是什么,因此操作系统必须维护一个映射,每个软件对应一个映射,将软件发出的地址映射到实际物理地址(注意:这是我们称之为“虚拟内存”概念的两个原因之一。软件不关心它们的数据存储在哪里的真实内存地址,它们只是即时输出地址,操作系统会找到合适的位置并在以后查找它们,如果需要的话)。

说设备刚刚开机,操作系统刚刚启动,现在没有其他进程运行(忽略操作系统,它也是一个进程!),你决定启动VLC。所以VLC从最低字节地址的RAM中分配了一部分。好的。现在当视频正在播放时,您需要启动浏览器查看某个网页。然后您需要启动记事本来记录一些文本。然后启动Eclipse进行编码...很快您的4 GB内存全部用完,RAM看起来像这样:

                                   enter image description here

问题1:现在你无法启动其他进程,因为所有的内存都被使用完了。因此,编写程序时必须考虑可用的最大内存(实际上可用的内存可能还要少,因为其他软件也会同时运行!)。换句话说,在你那破旧的1GB电脑上,你不能运行高内存消耗的应用程序。
好吧,现在你决定不再需要保持Eclipse和Chrome打开,你关闭它们以释放一些内存。这些进程占用的内存空间被操作系统回收,现在情况如下:

                                    enter image description here


假设关闭这两个进程会释放700 MB的空间 - (400 + 300)MB。现在你需要启动Opera,它将占用450 MB的空间。好吧,总的可用空间超过450 MB,但是...它不是连续的,而是分成单独的块,没有一个块足够大来容纳450 MB。所以你想到了一个绝妙的主意,让我们把所有进程尽可能地移到上面,这样就会在底部留下700 MB的空闲空间。这被称为压缩。很棒,除了...所有存在的进程都在运行。移动它们意味着移动所有内容的地址(记住,操作系统维护软件释放的内存的映射到实际内存地址。想象一下,软件释放了一个地址为45的数据123,操作系统将其存储在位置2012,并创建了一个条目在映射中,将45映射到2012。如果现在将软件移动到内存中,之前位于位置2012的内容将不再在2012处,而在新位置,操作系统必须相应地更新映射以将45映射到新地址,以便软件查询内存位置45时可以获得预期的数据(123). 就软件而言,它只知道地址45包含数据123!)!想象一下一个引用本地变量i的进程。在它再次访问时,它的地址已经改变了,它将无法再找到它。对于所有函数、对象、变量,基本上所有东西都有一个地址,移动一个进程意味着改变它们所有的地址。这就导致了:
问题2: 你无法移动一个进程。该进程中所有变量、函数和对象的值在编译期间由编译器硬编码,该进程在其生命周期内依赖于它们位于同一位置,并更改它们是昂贵的。因此,进程退出时会留下大量“空洞”。这被称为“外部碎片”。
好的。假设以某种神奇的方式,你成功地将进程向上移动。现在底部有700MB的可用空间。

                        enter image description here

Opera 流畅地适应在底部。现在你的 RAM 看起来像这样:

                                    enter image description here

很好。一切看起来都很好。然而,剩余的空间不多,现在你需要再次启动Chrome,这是一个已知的内存占用大户!它需要大量的内存才能启动,而你几乎没有留下任何空间......除非......你现在注意到一些最初占用大量空间的进程现在不需要太多空间了。也许你已经停止了在VLC中的视频播放,因此它仍然占用一些空间,但不像运行高分辨率视频时那样需要太多空间。同样的情况也适用于Notepad和Photos。你的RAM现在看起来是这样的:

                                        enter image description here

空洞问题又来了!回到起点!之前,空洞是由于进程终止导致的,现在是因为进程需要的空间比以前少了!你又面临同样的问题,空洞合并后产生的空间比所需空间更多,但它们分散在各处,在单独使用时没有太大用处。因此,你必须再次移动这些进程,这是一个昂贵的操作,并且非常频繁,因为进程在其生命周期内经常缩小。

问题3:进程在其生命周期内可能会缩小,留下未使用的空间,如果需要使用这些空间,则需要进行昂贵的操作,即移动许多进程。这被称为内部碎片

好的,现在,您的操作系统做了必要的事情,移动了进程并启动了Chrome,一段时间后,您的RAM看起来像这样:

enter image description here

很好。现在假设您再次在VLC中观看Avatar。它的内存需求将会增加!但是...没有空间供其增长,因为记事本紧贴在其底部。所以,所有进程都必须向下移动,直到VLC找到足够的空间!

问题4:如果进程需要增长,则这将是一项非常昂贵的操作。

好的。现在假设照片正在用于从外部硬盘加载一些照片。访问硬盘将您从缓存和RAM的领域带到比数量级慢得多的磁盘领域。痛苦地、不可撤销地、超然地慢。这是一个I/O操作,这意味着它不是CPU绑定(它恰恰相反),这意味着它现在不需要占用RAM。然而,它仍然固执地占用着RAM。如果您想同时启动Firefox,您就不能这样做,因为可用的内存不多,而如果Photos在其I/O绑定活动期间被移出内存,它将释放大量内存,接着是(昂贵的)压缩,接着是Firefox适合其中。

问题5:I/O绑定作业一直占用RAM,导致RAM被低效利用,而这些RAM在此期间可以被CPU绑定作业使用。

因此,正如我们所看到的,即使采用虚拟内存的方法,我们仍然有很多问题。
有两种方法可以解决这些问题 - {{paging}}和{{segmentation}}。让我们讨论{{paging}}。在这种方法中,进程的虚拟地址空间被映射到物理内存中的块 - 称为{{pages}}。一个典型的{{page}}大小为{{4 kB}}。映射是由称为{{page table}}的东西维护的,给定一个虚拟地址,我们现在只需要找出该地址属于哪个{{page}},然后从{{page table}}中找到该{{page}}在实际物理内存中对应的位置(称为{{frame}}),并且由于虚拟地址在{{page}}和{{frame}}中的偏移量相同,因此通过将该偏移量加到{{page table}}返回的地址上找到实际地址。例如:

enter image description here

左侧是进程的虚拟地址空间。假设虚拟地址空间需要40个内存单元。如果物理地址空间(右侧)也有40个内存单元,那么将所有左侧位置映射到右侧位置就成为可能,我们会非常高兴。但不幸的是,物理内存不仅可用内存单位更少(此处为24),而且还必须在多个进程之间共享!好吧,让我们看看我们如何应对。

当进程开始时,会发出一个内存访问请求,请求的位置为35。这里页面大小为8(每个页面包含8个位置,整个虚拟地址空间中共有40个位置,因此共有5个页面)。所以该位置属于第4页(35/8)。在该页面中,该位置的偏移量为335%8)。因此,该位置可以用元组(pageIndex, offset)=(4,3)来指定。这只是开始,所以进程的任何部分都还没有存储在实际物理内存中。因此,当前的页表为空,该页表维护了左侧页面到右侧实际页面(称为)的映射。因此,操作系统放弃CPU,让设备驱动程序访问磁盘并获取该进程的页面4(基本上是从磁盘上的程序中获取的内存块,其地址范围为3239)。当它到达时,操作系统将页面分配到RAM的某个位置,比如第一个帧,该进程的页表注意到页面4映射到RAM中的帧0。现在数据终于存在于物理内存中了。操作系统再次查询元组(4,3)页表,这次,页表表示页面4已经映射到RAM中的帧0。因此,操作系统直接转到RAM中的第0帧,在该帧中访问偏移量为3的数据(花点时间来理解一下。整个页面从磁盘上获取后,被移动到了中。因此,页面中单个内存位置的偏移量在帧中也是相同的,因为在页面/内,内存单元仍然位于相对的同一位置!),并返回数据!因为数据在第一次查询时没有在内存中找到,而必须从磁盘中获取并加载到内存中,所以它构成了一个缺失
好的。现在假设一个内存访问请求访问了位置28,它被转换为(3,4)。目前页表只有一个条目,将页面4映射到帧0。因此这又是一次缺页,进程放弃CPU,设备驱动程序从磁盘获取页面,进程再次控制CPU,并更新其页表。现在假设页面3映射到RAM中的帧1。因此(3,4)变成了(1,4),并返回RAM中该位置的数据。很好。以这种方式,假设下一个内存访问请求的位置是8,它被转换为(1,0)。页面1还没有在内存中,重复相同的过程,页面被分配到RAM中的帧2。现在RAM-进程映射看起来像上面的图片。此时,原本只有24个内存单元可用的RAM已经填满。假设该进程的下一个内存访问请求来自地址30。它映射到(3,6)页表显示页面3在RAM中,并且将其映射到帧1。太好了!因此数据从RAM位置(1,6)获取并返回。这构成了一个命中,因为所需的数据可以直接从RAM中获取,因此速度非常快。同样地,下几个访问请求,比如位置11322627都是命中,即进程请求的数据可以直接在RAM中找到,无需查找其他地方。
现在假设有一个对地址3的内存访问请求。它转化为(0,3),而该进程的页表目前有3个条目,对应于页面134,表示该页面不在内存中。与之前的情况类似,它从磁盘中获取,但不同的是,RAM已经填满了!那么现在该怎么办呢?这就是虚拟内存的美妙之处——从RAM中驱逐一个帧!(有各种因素来决定要驱逐哪个帧。它可以基于LRU,其中最近最少访问的帧是要被驱逐的。也可能是基于先进先出的原则,其中分配时间最长的帧被驱逐等等。)因此,某些帧被驱逐。假设我们随机选择了帧1。然而,那个映射到某个页面!(目前,它由页表映射到我们唯一的一个进程的第3页)。因此,必须告诉该进程这个悲惨的消息,即一个,不幸地属于你,将从RAM中驱逐出去,为其他页面腾出空间。该进程必须确保更新其页表以获取此信息,即删除该页面-帧对的条目,以便下次请求该页面时,它会正确地告诉该进程,该页面不再在内存中,并且必须从磁盘中获取。好的。因此,帧1被驱逐,页面0被带入并放置在RAM中,并且页面3的条目被删除,并被页面0替换,映射到相同的帧1。因此,我们的映射现在如下所示(请注意右侧第二个中的颜色变化):

enter image description here

看到刚才发生了什么了吗?该进程需要增长,需要比可用的RAM更多的空间,但与我们之前的情况不同,那时每个RAM中的进程都必须移动以适应增长的进程,这里只需进行一个页面替换即可!这是由于进程的内存不再需要连续,可以分块驻留在不同的位置,操作系统会维护它们的信息,并在需要时适当地查询它们。请注意:您可能会想,嗯,如果大部分时间都是未命中,数据必须不断从磁盘加载到内存中怎么办?是的,在理论上是可能的,但大多数编译器都是按照引用局部性的方式设计的,即如果使用某些内存位置的数据,则下一个所需的数据将位于非常接近的某个地方,可能来自同一页,刚刚加载到内存中的页面。因此,下一个未命中将在相当长的一段时间后发生,大多数即将到来的内存需求将由刚刚带入的页面或最近使用的页面满足。完全相同的原则也允许我们驱逐最近最少使用的页面,逻辑是很久没有使用的东西也不太可能再被使用。然而,并非总是如此,在特殊情况下,性能可能会受到影响。稍后再详细了解。
解决方案4:如果遇到空间问题,进程现在可以轻松增长,只需进行简单的页面替换,而不需要移动任何其他进程。
解决方案1:进程可以访问无限内存。当需要更多内存时,磁盘用作备份,所需的新数据从磁盘加载到内存中,并将最近未使用的数据“帧”(或“页”)移到磁盘上。这可以无限进行,由于磁盘空间便宜且几乎无限,因此它给人一种无限内存的错觉。另一个名为“虚拟内存”的原因是,它给你一种并不真正可用的内存的错觉!
很酷。早些时候我们遇到了一个问题,即使进程缩小,其他进程也难以重新获得空闲空间(因为这需要昂贵的压缩操作)。现在很容易了,当进程变小时,它的许多页面不再使用,因此当其他进程需要更多内存时,一个简单的基于LRU的清除程序会自动从RAM中清除那些不常用的页面,并用其他进程的新页面替换它们(当然还要更新所有这些进程的页面表以及原始进程占用更少空间),所有这些都不需要任何昂贵的压缩操作!
解决方案3:每当进程缩小时,其在RAM中的“框架”将不再被使用,因此一个简单的基于LRU的清除程序可以将这些页面清除并用新进程所需的页面替换它们,从而避免了内部碎片而无需进行压缩。

对于问题2,请花点时间理解,这种情况已经完全被移除了!现在不需要移动一个进程来适应一个新的进程,因为整个进程永远不需要一次性全部适应,只有某些页面需要临时适应,这是通过从RAM中驱逐来实现的。所有操作都是以页面为单位进行的,因此现在没有空洞的概念,因此也没有任何移动的问题!也许由于这个新需求,需要移动10个页面,但还有成千上万个页面没有受到影响。而之前,所有进程(每一位)都必须被移动!

问题2的解决方案:为了容纳一个新的进程,只需要根据需要清除其他进程中最近未使用的部分的数据,并以固定大小的单位称为页面进行操作。因此,这个系统不存在空洞外部碎片的可能性。

现在,当进程需要执行一些I/O操作时,它可以轻松地放弃CPU!操作系统只需从RAM中驱逐其所有页面(可能将其存储在某个缓存中),而新进程同时占用RAM。当I/O操作完成后,操作系统只需将这些页面恢复到RAM中(当然是通过替换其他进程的页面,可能是替换原始进程的进程,也可能是需要执行I/O操作的进程之一,并因此可以放弃内存!)

问题5的解决方案:当进程执行I/O操作时,它可以轻松地放弃RAM使用权,这可以被其他进程利用。这导致了RAM的合理利用。

当然,现在没有进程直接访问RAM。每个进程都访问一个虚拟内存位置,该位置映射到一个物理RAM地址,并由该进程的页表维护。映射由操作系统支持,操作系统让进程知道哪个框架为空,以便为进程安装新页面。由于该内存分配由操作系统本身监督,因此它可以轻松确保没有进程通过仅从RAM中分配空框架或通过侵入RAM中另一个进程的内容而侵犯另一个进程的内容,通信以更新其页表

原始问题的解决方案:由于整个分配是由操作系统本身管理的,并且每个进程都在其自己的沙盒化虚拟地址空间中运行,因此不存在一个进程访问另一个进程内容的可能性。
因此,分页(除其他技术外),结合虚拟内存,支持了当今运行在操作系统上的软件!这使得软件开发人员不必担心用户设备上有多少可用内存,在哪里存储数据,如何防止其他进程破坏他们软件的数据等等。但是,它当然不是绝对可靠的。存在以下缺陷:
  1. 分页最终通过使用磁盘作为辅助备份来给用户提供无限内存的幻觉。从辅助存储器检索数据以适应内存(称为页面交换,在RAM中找不到所需页面的事件称为页面错误)是一种IO操作,因此很昂贵。这会减慢进程速度。连续进行多次此类页面交换后,进程变得非常缓慢。你是否曾经看到过你的软件正常运行,突然变得非常缓慢,几乎挂起或只能重启?可能是太多的页面交换导致其变慢(称为抖动)。
因此回到OP,

为什么我们需要虚拟内存来执行进程? - 正如答案详细解释的那样,为了给软件一种设备/操作系统具有无限内存的假象,使得任何大小的软件都可以运行,而不必担心内存分配或其他进程损坏其数据,即使在并行运行时也是如此。这是一个概念,通过各种技术实现,其中之一,如本文所述,是分页。它也可能是分段

当从外部硬盘驱动器将进程(程序)带到主内存(物理内存)进行执行时,这个虚拟内存位于哪里? - 虚拟内存本身并不存在,它是一个抽象概念,总是存在的。当软件/进程/程序启动时,会为其创建一个新的页表,并包含从该进程输出的地址到实际RAM中的物理地址的映射。由于进程输出的地址不是真实地址,在某种意义上,它们实际上就是虚拟内存

谁负责虚拟内存,虚拟内存的大小是多少? - 由操作系统和软件共同负责。想象一下你代码中的一个函数(最终编译并制成可执行文件),其中包含一个局部变量 - 一个 int i。当代码执行时,i 在函数堆栈中获得一个内存地址。该函数本身作为一个对象存储在其他地方。这些地址是编译器生成的(编译你的代码成为可执行文件的编译器)- 虚拟地址。当执行时,i 必须至少在该函数的实际物理地址中驻留一段时间(除非它是静态变量!),因此操作系统将编译器生成的 i 的虚拟地址映射到实际物理地址,以便在该函数中的某些代码需要 i 的值时,该进程可以查询 OS 获取该虚拟地址,然后 OS 可以查询存储的物理地址以获取存储的值,并返回它。 假设 RAM 的大小为 4GB(即 2^32-1 个地址空间),虚拟内存的大小是多少? - RAM 的大小与虚拟内存的大小无关,它取决于操作系统。例如,在 32 位 Windows 上,它是 16 TB,在 64 位 Windows 上,它是 256 TB。当然,它还受磁盘大小的限制,因为那里备份了内存。

8
这是一篇深入的VM/分页描述(应该在某个博客上)。我不太理解关于VM映射/分页的一个部分,即每次页面错误或交换仍然需要(看起来)大量磁盘访问。每个页面交换(从VM到磁盘和反之亦然)是否都会调用一次磁盘的读取/写入?这对我来说似乎是一个巨大的开销。 - Aroic
@TMartin 是的,页面被写入了pagefile.sys文件中,我相信有两次写操作,一次是为了页面,另一次是为了存储在pagefile内部数组中的PFN。LRU算法确保大多数来自每个进程工作集(最老的年龄)的最少访问PTE的页面将被发送到待机列表,并最终分页出去,因此很有可能在再次访问页面之前,该页面已经被写入磁盘并在后台发生。此外,在整个过程中这是一个相对不常见的事件;希望大多数页面故障都是软性的。 - Lewis Kelsey
备用列表也有自己的优先级系统,当零和空闲列表为空时,它将以最低优先级开始换出备用页面。我不确定优先级是基于什么的,但它可能对应于先前的LRU年龄。 - Lewis Kelsey
是的,我也是这么想的。也许你应该在描述问题的部分加上“操作系统要做的工作太多”的短语。这对于未来的读者会有很大的帮助! - ajaysinghnegi
@SexyBeast **"当进程开始时,会发出一个访问位置35的内存访问请求"**,但在同一段落中 - "这只是开始,因此进程的任何部分尚未存储在实际物理内存中"。如果进程的任何部分尚未存储在物理内存中,那么它如何启动?如果是这样,它怎么能够对loc 35进行请求呢?我的猜测是 - _需要启动进程/程序的部分已加载到内存中,并且在执行该部分时需要访问loc 35_。这样对吗?感谢您写得好的答案! - Ambareesh
显示剩余2条评论

102

虚拟内存在IT技术中是一个抽象概念,它为程序员提供了有无限内存的幻觉。

虚拟内存映射与实际物理地址相对应。操作系统通过页表等数据结构来创建和处理这些映射。虚拟内存映射总是在页表或某些类似的数据结构中(如果是其他虚拟内存实现方式,我们可能不应该称之为“页表”)。页表也位于物理内存中 - 通常位于内核保留空间中,因此用户程序无法覆盖。

虚拟内存通常比物理内存大 - 如果虚拟内存和物理内存大小相同,则几乎没有必要进行虚拟内存映射。

通常只有程序的需要部分驻留在内存中 - 这是一个称为“分页”的主题。虚拟内存和分页密切相关,但并非完全相同的话题。还有其他虚拟内存实现,例如分段。

我可能猜错了,但我敢打赌你难以理解的问题与特定的虚拟内存实现有关,很可能是分页。没有一种完全正确的分页方法 - 有许多实现,您的教科书描述的方法可能与出现在Linux / Windows等真实操作系统中的方法略有不同 - 可能存在细微差异。

我可以在分页上闲扯一千段落......但我认为最好针对特定的主题进行不同的问题。


5
将虚拟内存和物理内存设置成相同大小是有原因的。虚拟内存允许不同的进程拥有自己的地址空间,这可以保护一个进程的数据不被其他进程覆盖。它还可以让你为不同的地址空间授予不同的权限,使得系统中的某些用户可以拥有更高的读/写权限。但是,将虚拟内存和物理内存设置成相同大小的确会消除虚拟内存的存储优势。 - almel
2
补充almel的评论:即使虚拟内存比物理内存小或相同大小,也有以下好处:除了安全和稳定性方面的好处外,多个32位程序可以全部在内存中运行(例如在64位系统上),物理内存可以更好地管理以避免一些碎片化问题,透明写时复制内存技术需要虚拟内存等。 - Kaganar
2
请注意,虚拟内存绝不是“无限的”,也不会有这样的设计意图来激发任何这样的幻想。AMD64架构目前允许对虚拟内存进行48位寻址(AMD APM Vol 2. pg. 120)。尽管使用情况各不相同,但可以说一个主要优点是能够保留比在物理空间中通常可能的更大、连续的地址空间运行。然后,这个保留的范围将根据需要提交,这可能消除了链接结构以及重新分配的需要。 - awdz9nld
@WaterCoolerv2 我比较喜欢Umakishore Ramachandran的《计算机系统:架构和操作系统的综合方法》。虽然这是一本教科书,但我认为它相当全面,并且与其他关于操作系统的书籍相比,解释得更好。但实际上,任何有关操作系统的书籍都可能涵盖分页、虚拟内存等主题。 - PinkElephantsOnParade
@PinkElephantsOnParade:谢谢。我有很多关于操作系统的书籍,既有涵盖操作系统概念的通用书籍,也有关于Windows内部和Win API的特定书籍,我会不时地参考它们。我会阅读你推荐的那本书。 - Water Cooler v2
显示剩余2条评论

17

VIRT -- 虚拟大小 (kb) 任务正在使用的虚拟内存总量。它包括所有代码、数据和共享库以及已经被交换出去但没有被使用的页面。

SWAP -- 交换大小 (kb) 非驻留的内存,但存在于一个任务中。这是被交换出去但可能包括其他非驻留内存的内存。此列通过从虚拟内存中减去物理内存来计算。


9
请查看这里:物理内存和虚拟内存的区别 虚拟内存在硬盘上存储,当RAM已满时使用。物理内存受限于计算机中安装的RAM芯片的大小。虚拟内存受限于硬盘的大小,因此虚拟内存具有更大的存储能力。

虚拟内存是存储在硬盘上的,位于交换文件/分区中吗? - BruceJohnJennerLawso
5
@BruceJohnJennerLawso说:“不,virtual = swap + physical。”意思是虚拟等于交换加物理。 - RickyA
同意@RickyA的观点,虚拟 >= 物理。 - hastrb

6

物理内存:物理内存指计算机中的RAM或主存储器。物理内存是一种易失性内存,因此需要持续供电以保留数据。

虚拟内存是一种逻辑内存。换句话说,它是由操作系统执行的内存管理技术。虚拟内存允许程序员使用比实际可用的物理内存更多的内存来运行程序。如果物理内存为4GB,虚拟内存为16GB,则程序员可以使用这16GB虚拟内存来执行程序。使用虚拟内存,他可以执行需要大于物理内存的复杂程序。

物理内存和虚拟内存之间的主要区别在于,物理内存是指连接到主板的实际RAM,而虚拟内存是一种内存管理技术,允许用户执行大于实际物理内存的程序。


所以虚拟内存有点像操作系统对内存的“心理模型”,访问某些虚拟内存部分需要到硬盘/固态硬盘进行访问,因为它可能比物理内存大。 - jacob_g

0

因此,任何程序通常需要从内存(物理地址)中存储/读取数据。 CPU 生成称为逻辑地址空间的地址空间,这是一组可用于访问内存中程序的地址,因为逻辑地址空间对应于实际地址。

逻辑地址空间中的地址称为逻辑地址虚拟地址,而与它们相对应的一组地址在物理内存中被称为物理地址空间,每个地址称为物理地址,即内存中的实际地址。

注意: 内存管理单元MMU负责进行地址绑定。

来源:“操作系统概念作者:阿伯拉罕·西尔伯沙茨(Abraham Silberschatz) (第8章内存管理策略)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接