为什么 Debian Linux 允许每个进程最多 128TiB 的虚拟地址空间,但只允许 64TiB 的物理内存?

23 debian virtual-memory linux-kernel

我刚在这里读到:

  • 每个进程最多 128TiB 虚拟地址空间(而不是 2GiB)
  • 64TiB 物理内存支持而不是 4GiB(或 64GiB 与 PAE 扩展)

这是为什么?我的意思是,物理内存支持受到内核或当前硬件的限制?

为什么您需要的虚拟内存空间是实际可寻址的物理内存的两倍?

Gil*_*il' 34

这些限制不是来自 Debian 或 Linux,而是来自硬件。不同的架构(处理器和内存总线)有不同的限制。

在当前的 x86-64 PC 处理器上,MMU 允许48 位虚拟地址空间。这意味着地址空间被限制为 256TB。用一位来区分内核地址和用户地址,这就为进程的地址空间留下了 128TB。

在当前的 x86-64 处理器上,物理地址最多可以使用 48 位,这意味着您最多可以拥有 256TB。自从引入 amd64 体系结构以来,限制逐渐增加(如果我没记错的话,从 40 位开始)。地址空间的每一位都需要一些布线和解码逻辑(这使得处理器更昂贵、更慢、更热),因此硬件制造商有动力减小尺寸。

Linux 只允许物理地址增加到 2^46(所以你最多只能有 64TB),因为它允许物理内存完全映射到内核空间。请记住,地址空间有 48 位;内核/用户的一位留下内核地址空间的 47 位。其中一半最多直接寻址物理内存,另一半允许内核映射它需要的任何内容。(Linux 可以处理无法同时完全映射的物理内存,但这会带来额外的复杂性,因此只能在需要的平台上完成,例如带有 PAE 的 x86-32和带有 LPAE 的 armv7。)

由于以下几个原因,虚拟内存大于物理内存很有用:

  • 它让内核映射整个物理内存,并为额外的虚拟映射留出空间。
  • 除了物理内存的映射,还有交换、文件和设备驱动程序的映射。
  • 在某些地方使用未映射的内存很有用:保护页面以捕获缓冲区溢出、由于ASLR导致的大型未映射区域等。

  • 物理内存的 46 位限制与 [Linux 内存映射](https://www.kernel.org/doc/Documentation/x86/x86_64/mm.txt) 相关:它包括物理内存的完整映射内核空间,这意味着物理内存只能对应可用地址空间的四分之一。 (9认同)

小智 8

我不知道为什么,但我能想到支持物理内存两倍的地址空间会很有用的七个原因。

  1. 第一个是您可以运行需要额外内存的应用程序——即使这意味着要交换到磁盘。
  2. 更清洁的内存布局以分区内存使用。例如,操作系统可能会采用编号较高的地址,并为应用程序保留编号较低的地址,以使分离更清晰。
  3. 地址空间布局随机化更有效一些。
  4. 将页面标记为可执行可能意味着剩余内存。
  5. 内存映射 I/O。
  6. 内存分配更容易:一次可以分配更大的块。
  7. 减少内存碎片

  • (3) 也很重要。你**真的**想要一个比你将分配的内存量大几个数量级的虚拟地址空间,这样随机猜测几乎肯定会导致陷阱。 (2认同)

der*_*ert 5

这些是硬件限制。当前的 x86_64/amd64 硬件允许 48 位虚拟地址和各种大小(取决于实现——例如,我的工作站在这里只支持 36 位)物理地址。Linux 内核将虚拟地址空间分成两半(内核使用一半,用户空间使用一半——就像在 x86 上一样)。

所以你得到:

2?? 字节÷ 2 = 2?? 字节 = 128 TiB

物理地址大小通常较小,因为它实际上是物理地址。它占用 CPU 上/中的引脚/焊盘、晶体管、连接等,以及板上的走线。芯片组中可能也是如此。在处理器内核或插槽的设计寿命内支持无法想象的内存数量是没有意义的——所有这些都需要花钱。(即使每个插槽有 32 个 DIMM 插槽和 64GiB DIMM,你仍然只有 2TiB。即使 DIMM 容量每年翻一番,我们距离 64TiB 也有 5 年的时间。

正如Peter Cordes指出的那样,人们现在正在将3D XPoint等非易失性存储连接到内存总线,这使得地址空间耗尽成为可能。较新的处理器已将物理地址空间扩展到 48 位;Debian wiki 可能还没有更新。