看到这个问题问了很多次。但是找不到合理的答案。虚拟内存的实际限制是多少?
它是 CPU 的最大可寻址大小吗?例如,如果 CPU 是 32 位,那么最大值是 4G?
还有一些文本将其与硬盘区域相关联。但我找不到这是一个很好的解释。有人说它是 CPU 生成的地址。
我们看到的所有地址都是虚拟地址?例如,我们在使用 GDB 调试程序时看到的内存位置。
CPU产生虚拟地址背后的历史原因?一些文本可互换地使用虚拟地址和逻辑地址。它有什么不同?
看到这个问题问了很多次。但是找不到合理的答案。虚拟内存的实际限制是多少?
它是 CPU 的最大可寻址大小吗?例如,如果 CPU 是 32 位,那么最大值是 4G?
还有一些文本将其与硬盘区域相关联。但我找不到这是一个很好的解释。有人说它是 CPU 生成的地址。
我们看到的所有地址都是虚拟地址?例如,我们在使用 GDB 调试程序时看到的内存位置。
CPU产生虚拟地址背后的历史原因?一些文本可互换地使用虚拟地址和逻辑地址。它有什么不同?
不幸的是,答案是“视情况而定”。您没有提到操作系统,但在提到 GDB 时暗示了 linux。我会尽量在我的回答中完全笼统。
基本上存在三种不同的“地址空间”。
第一个是逻辑地址空间。这是指针的范围。现代(386 或更高)具有内存管理单元,允许操作系统使您的实际(物理)内存出现在任意地址。对于典型的台式机,这是以 4KB 块完成的。当程序访问某个地址的内存时,CPU 将查找与该逻辑地址对应的物理地址的位置,并将其缓存在 TLB(翻译后备缓冲区)中。这允许三件事:首先,它允许操作系统为每个进程提供尽可能多的地址空间(直到指针的整个范围 - 如果有 API 允许程序映射/取消映射其地址空间的部分,则超出范围) )。其次,它允许它通过切换到不同的内存映射来完全隔离不同的程序,使一个程序不可能破坏另一个程序的内存。第三,它为开发人员提供了调试帮助——随机损坏的指针可能指向一些根本没有映射的地址,导致“分段错误”或“无效页面错误”或其他任何术语,术语因操作系统而异。
第二个地址空间是物理内存。它只是您的 RAM - 您的 RAM 数量是有限的。也可能有具有内存映射 I/O 的硬件 - 看起来像 RAM 的设备,但它实际上是一些硬件设备,如 PCI 卡,或者可能是视频卡上的内存等。
第三种地址是虚拟地址空间。如果您的物理内存 (RAM) 比程序所需的少,则操作系统可以模拟拥有更多 RAM,方法是让程序产生一种拥有大量 RAM 的错觉,即只有一部分实际是 RAM,其余部分是在“交换文件”中。例如,假设您的机器有 2MB 的 RAM。假设一个程序分配了 4MB。会发生的是操作系统将保留 4MB 的地址空间。操作系统将尝试在实际 RAM 中保留 4MB 中最近/最常访问的部分。任何不经常/最近访问的部分都将复制到“交换文件”中。现在,如果程序接触到实际不在内存中的 4MB 的一部分,CPU 将产生“页面错误”。操作系统会找到一些最近没有被访问过的物理内存,然后“page in”那个页面。它可能必须先将该内存页面的内容写入页面文件,然后才能对正在访问的数据进行分页。这就是为什么它被称为交换文件 - 通常,当它从交换文件中读取某些内容时,它可能必须先写出一些内容,从而有效地将内存中的某些内容与磁盘上的某些内容进行交换。
典型的 MMU(内存管理单元)硬件跟踪访问(即读取)和修改(即写入)的地址。典型的分页实现通常会在分页时将数据留在磁盘上。这允许它“丢弃”尚未修改的页面,避免在交换时写出页面。典型的操作系统会定期扫描页表并保留某种数据结构,使其能够智能且快速地选择哪些物理内存没有被修改,并随着时间的推移建立关于内存中哪些部分经常更改以及哪些部分的信息不。
典型的操作系统通常会轻轻地分出不经常更改的页面(轻轻地因为它们不想生成太多会干扰您的实际工作的磁盘 I/O)。这允许它在交换操作需要内存时立即丢弃页面。
典型的操作系统会尝试使用所有“未使用”的内存空间来“缓存”(保留副本)被访问的文件片段。内存比磁盘快数千倍,因此如果经常读取某些内容,将其放在 RAM 中会大大加快速度。通常,虚拟内存实现将与此“磁盘缓存”相结合,作为可以快速回收用于交换操作的内存源。
编写一个有效的虚拟内存管理器是极其困难的。它需要动态适应不断变化的需求。
典型的虚拟内存实现感觉非常慢。当一台机器开始使用比 RAM 多得多的内存时,整体性能会变得非常非常糟糕。