【问题标题】:What is virtual memory? [duplicate]什么是虚拟内存? [复制]
【发布时间】:2020-02-11 16:15:20
【问题描述】:

什么是虚拟内存,它与物理内存 (RAM) 有何不同?它说物理内存存储在主板上,而虚拟内存存储在磁盘上。

它还说只有在物理内存被填满时才使用虚拟空间,这让我很困惑。

那么,为什么 Windows 使用虚拟内存?是不是因为内存空间小,不是为大存储而设计的,所以使用虚拟存储更多更大的东西?

接下来是关于地址的。由于虚拟在磁盘上,它们不应该共享物理地址。 所以他们有独立的地址。对吗?

还有,

在写另一个进程的内存时,为什么推荐使用 VirtualAlloc 而不是 HeapAlloc?

虚拟内存依赖于进程,物理内存通过进程共享是真的吗?

【问题讨论】:

  • “为其他进程收集内存时”,这是什么意思?
  • 另外,那个副本似乎并没有真正回答这个问题的要点......
  • @hyde 抱歉,我的意思是写作。我做了修改。
  • why Windows uses virtual memory? 所有现代多任务桌面操作系统都使用虚拟内存。这不是因为 RAM 很小。这只是提供进程之间分离的一种方式
  • 我还是不知道“写另一个进程的内存”到底是什么意思。

标签: c windows winapi memory virtual-memory


【解决方案1】:

“虚拟内存”意味着有一个有效的地址空间,它不映射到任何特定的物理内存或存储,因此 虚拟。在现代通用操作系统的上下文中,每个进程都有自己的虚拟内存空间,虚拟内存地址重叠。

这个地址空间被分成几页以便于管理(示例大小为 4 KB)。每个有效页面可以处于 3 种不同的状态:

  • 未物理存储(假定全为 0)。如果进程写入此类页面,则需要为其分配物理内存页面(由操作系统,见下文),以便存储值。
  • 映射到物理内存,意味着计算机RAM中的一些页面大小的区域存储内容,并且可以直接被进程使用。
  • 交换到磁盘(可能是交换文件),以释放物理 RAM 页面(由操作系统自动完成)。如果进程访问页面(读取或写入),则需要先将其加载到 RAM 中的页面(见上文)。

只有当虚拟内存页面映射到物理 RAM 页面时,才有东西存在。在其他情况下,如果进程访问该页面,则会出现 CPU 异常,它将控制权转移给操作系统。然后,操作系统需要将该虚拟内存页面映射到 RAM(可能需要首先通过将当前数据交换到交换文件来释放一些 RAM,或者如果内存不足则终止某些应用程序)并将正确的数据加载到其中,或者它可以终止应用程序(地址不在有效范围内,或只读但进程尝试写入)。

同一页内存也可以一次映射到多个地方,例如共享内存,因此多个进程可以同时访问相同的数据(虚拟地址可能不同,因此不能共享指针变量)。

另一个使用虚拟内存的特殊情况是将磁盘上的常规文件映射到虚拟内存(与交换文件发生的情况相同,但现在由正常的应用程序进程控制)。然后操作系统负责从磁盘实际读取字节(以页面大小的块为单位)并将更改写回,该进程可以像访问任何内存一样访问内存。


每个现代多任务通用操作​​系统都使用虚拟内存,因为它们运行的​​ CPU 支持它,并且因为它解决了一大堆问题,例如内存碎片、透明地使用交换到磁盘、内存保护......它们可以通过不同的方式解决,但虚拟内存是当今的方式。


进程之间共享物理内存的方式与共享计算机电源或共享 CPU 的方式相同。它是物理计算机的一部分。一个正常的进程从不处理实际的物理内存地址,它所看到的只是虚拟内存,它可能映射到不同的物理位置。

虚拟内存的内容通常不共享,除非它们是共享的(例如使用共享内存时)。


不确定您的意思是“为其他进程收集内存时”,所以无法回答。

【讨论】:

  • 稍微扩展他的特殊情况示例,这是一种优化技术,可以避免不必要的额外内存分配。从磁盘加载模块时,操作系统将确定该模块是否已存在于物理内存中的某个位置。如果是这样,那么就没有必要为它分配一个全新的物理内存区域,而是保留虚拟地址范围并指向先前分配的物理内存。如果你在内存中修改这个模块,那么它会被重新映射到一个单独的物理页面中。
【解决方案2】:

虚拟内存本质上可以被认为是映射到物理地址的每个进程的虚拟地址。在 x86 的情况下,有一个寄存器 CR3 指向该进程的转换表。分配新内存时,操作系统将分配物理内存,甚至可能不连续,然后设置一个空闲的连续虚拟区域指向该物理内存。每当 CPU 访问任何虚拟内存时,它都会使用 CR3 中的转换表将其转换为实际的物理地址。

更多信息 https://en.m.wikipedia.org/wiki/Control_register#CR3
https://en.m.wikipedia.org/wiki/Page_table

【讨论】:

  • 虚拟内存是进程依赖的,物理内存是进程共享的吗?
  • 虚拟内存依赖于进程,物理内存不是,但只能从内核模式访问。
  • 为了进一步澄清,物理内存当然是数据实际驻留在 RAM 中的位置。虚拟内存由 CPU 支持,但实际上并不指向任何真实的地方,它更多的是一个概念,虚拟地址本身保留了几个位范围,用于将条目编码到转换表中。
  • (续...) CPU 有很多特殊的寄存器和标志来确定它应该如何执行代码以及它所处的特权级别。每当代码在用户模式下执行时,都无法直接读取物理内存。就 CPU 而言,可用的完整地址空间是内部进程虚拟内存。在内核中,您可以将物理地址映射到虚拟地址,然后读取它。
  • 说“物理内存......只能从内核模式访问”可能会被误解为暗示进程必须通过内核才能读取/写入物理内存。但是只有在出现页面错误时才会涉及内核,以便将页面从页面文件加载回物理内存。对于有效页面,进程上下文中的地址转换由 CPU 中的内存管理单元自动处理,它甚至具有专用缓存以最小化成本,称为translation lookaside buffers。
【解决方案3】:

引用Wikipedia:

在计算中,虚拟内存(也称为虚拟存储)是一种内存管理技术,它提供“对给定机器上实际可用的存储资源的理想化抽象”,它“给非常大(主要) 内存。”

由于虚拟内存是一种虚幻的内存(因此,不存在),因此使用了其他一些计算机资源而不是 RAM。在这种情况下,使用的资源是磁盘,因为它有很多空间,比 RAM 还多,操作系统可以在其中运行其 VM 内容。

它还说只有在物理内存被填满时才使用虚拟空间,这让我很困惑。

不应该。 VM 使用磁盘,磁盘的 I/O 比 RAM 的 I/O 慢得多。这就是为什么现在首选物理内存,而当物理内存不够时使用VM的原因。

那么,为什么 Windows 使用虚拟内存呢?是不是因为内存空间小,不是为大存储而设计的,所以使用虚拟存储更多更大的东西?

这是主要原因之一,是的。在过去(70 年代),计算机内存非常昂贵,因此必须构思解决方法。

【讨论】:

  • 您的第一条评论引用了内存分页,它根本与虚拟内存没有直接关系。您的第二条评论再次错误分页虚拟内存。你最后的回答不准确。虚拟内存主要用于安全地分离每个单独进程的内存访问,但历史还有更多。
  • 非常感谢您的回答。我还有一个问题,在为其他进程收集内存时,为什么推荐使用 VirtualAlloc 而不是 HeapAlloc?
  • @AkutaHinako 很遗憾,我不知道怎么回答。
  • 附上我之前的评论,分页是指如果操作系统确定它不可能很快被访问,则内存被“分页”。在这种情况下,操作系统会将该内存复制到磁盘 (C:\Pagefile.sys iirc),同时释放它映射到的物理内存。如果稍后访问内存,则会触发页面错误,并且操作系统将从页面文件中重新映射物理内存。
  • VirtualAlloc 导致 NtAllocateVirtualMemory 分配一个新的物理页面(最小 PAGE_SIZE 或 Windows 上的 0x1000)并设置虚拟地址转换。 HeapAlloc 更加优化,仅在需要时分配新页面。
猜你喜欢
  • 1970-01-01
  • 2014-12-16
  • 1970-01-01
  • 1970-01-01
  • 2021-06-10
  • 2016-07-24
  • 2022-08-12
  • 2011-02-22
  • 2017-12-08
相关资源
最近更新 更多