在64位地址空间中是否更容易获得连续内存?如果是,为什么



这篇博客中的一条评论写道:

我们知道如何制作大块的堆,但会有一些开销使用它们。我们对更快的存储管理的要求比我们在32位JVM中为更大的堆做这件事。如果你真的想要大堆,切换到64位JVM。我们仍然需要连续存储器,,但在64位地址空间中获取要容易得多

上述语句的含义是,在64位地址空间中获得连续内存更容易。这是真的吗?如果是,为什么?

这是非常正确的。进程必须从虚拟内存地址空间中分配内存。它存储代码和数据,其大小受体系结构寻址能力的限制。在32位进程中,地址永远不能超过2^32字节,这还不包括库切换技巧。这是4GB。操作系统通常也会从中提取很大一部分,例如在32位Windows上,它将可寻址虚拟机的大小减少到2GB。

理想情况下,分配是为了使它们紧密地结合在一起。这在实践中很少奏效。共享库或DLL尤其需要选择一个首选加载地址,并且在构建库时必须提前猜测。

因此,在实践中,分配是从现有孔之间的孔中进行的,并且您可以获得的最大可能连续分配受到最大孔大小的限制。通常比可寻址虚拟机的大小小得多,在Windows上,它通常在650兆字节左右。从那时起,由于可用地址空间因分配而变得碎片化,这种情况往往会下降。尤其是那些无法承受压缩垃圾收集器移动分配的本机代码。如果您使用Windows,则可以通过SysInternals的VMMap实用程序了解VM分配情况。

这个问题在64位处理中完全消失。理论上可寻址的虚拟内存大小是2^64,这是一个巨大的数字。如此之大以至于目前的处理器无法实现它,它们可以达到2^48。受操作系统版本的进一步限制,以及它是否愿意为这么多VM保留页面映射表。8 TB是一个典型的限制。言下之意,分配之间的漏洞是巨大的。您的程序在因OOM而死亡之前,将在分页文件的颠簸中崩溃。

我不能清楚地说明JVM是如何实现的,但从纯粹的理论角度来看,如果你有一个明显更大的虚拟地址空间(例如,与32位相比,64位),那么找到一大块可供分配的连续内存应该会容易得多(极端情况下,你没有机会在32位地址空间中找到4GB的连续可用内存,但很有可能在整个64位地址空间找到这个空间)。

应该注意的是,无论虚拟地址空间大小如何,这仍然将通过分配(可能)不连续的物理内存页来实现,特别是在请求的分配很大的情况下——更大的虚拟地址空间只意味着可能有更多的连续虚拟地址可供使用。

最新更新