33

-Xmx在 32 位系统中可以设置的理论最大堆值当然是2^32字节,但通常(请参阅:了解最大 JVM 堆大小 - 32 位与 64 位)不能使用全部 4GB。

对于在 64 位机器上运行在 64 位操作系统中的 64 位 JVM,除了2^64字节或 16 艾字节的理论限制之外,还有其他限制吗?

我知道由于各种原因(主要是垃圾收集),过大的堆可能不明智,但是鉴于阅读了有关具有 TB RAM 的服务器的信息,我想知道什么是可能的

4

6 回答 6

24

如果要使用 32 位引用,则堆限制为 32 GB。

但是,如果您愿意使用 64 位引用,则大小可能会受到操作系统的限制,就像使用 32 位 JVM 一样。例如,在 Windows 32 位上,这是 1.2 到 1.5 GB。

注意:您将希望您的 JVM 堆适合主内存,最好在一个 NUMA 区域内。在更大的机器上,这大约是 1 TB。如果您的 JVM 跨越 NUMA 区域,则内存访问,特别是 GC 将花费更长的时间。如果您的 JVM 堆开始交换,则可能需要数小时才能进行 GC,甚至可能使您的机器无法使用,因为它会破坏交换驱动器。

注意:即使在堆中使用 32 位引用,也可以访问大的直接内存和内存映射大小。即使用远高于 32 GB。

Hotspot JVM 中的压缩 oops

压缩的 oop 将托管指针(在 JVM 中的许多但不是所有地方)表示为 32 位值,必须将其缩放 8 倍并添加到 64 位基址才能找到它们所引用的对象。这允许应用程序处理多达 40 亿个对象(而不是字节),或高达约 32Gb 的堆大小。同时,数据结构紧凑性与 ILP32 模式具有竞争力。

于 2011-10-05T14:48:59.813 回答
3

答案显然取决于 JVM 的实现。Azul 声称他们的 JVM

可以扩展到...超过 1/2 TB 的内存

通过“可以扩展”,它们似乎意味着“运行良好”,而不是“完全运行”。

于 2011-10-05T14:49:59.380 回答
2

Windows 对每个进程施加内存限制,您可以在此处查看每个版本的内存限制

看:

User-mode virtual address space for each 64-bit process; With IMAGE_FILE_LARGE_ADDRESS_AWARE set (default): x64: 8 TB Intel IPF: 7 TB 2 GB with IMAGE_FILE_LARGE_ADDRESS_AWARE cleared

于 2011-10-05T14:52:00.947 回答
0

我尝试-Xmx32255M被 vmargs 接受用于压缩 oops。

于 2012-10-12T10:17:41.133 回答
0

对于在 64 位机器上运行在 64 位操作系统中的 64 位 JVM,除了 2^64 字节或 16 艾字节的理论限制之外,还有其他限制吗?

您还必须考虑硬件限制。虽然指针可能是 64 位,但当前 CPU 只能寻址不到 2^64 字节的虚拟内存

使用未压缩的指针,热点 JVM 需要为其堆提供连续的虚拟地址空间块。因此,硬件之后的第二个障碍是提供如此大块的操作系统,并非所有操作系统都支持这一点。

第三个是实用性。即使您可以拥有那么多虚拟内存,但这并不意味着 CPU 支持那么多物理内存,并且没有物理内存您最终会进行交换,这将对 JVM 的性能产生不利影响,因为 GC 通常必须接触很大一部分堆的。

正如其他答案提到的压缩 oops:通过将对象对齐提高到 8 个字节以上,压缩 oops 的限制可以增加到 32GB 以上

于 2015-08-20T08:55:22.173 回答
-2

从理论上讲,一切皆有可能,但实际上您会发现数字远低于您的预期。我一直试图经常解决服务器上的巨大空间问题,发现即使服务器可以拥有大量内存,但令我惊讶的是,大多数软件实际上永远无法在实际场景中解决它,这仅仅是因为 CPU 速度不够快,无法真正解决它们. 为什么说对?!. 时间就是我工作过的每台巨大机器的无休止的垮台。因此,我建议不要仅仅因为可以解决大量问题而过火,而是使用您认为可以使用的东西。实际值通常远低于您的预期。当然,我们当中没有人真正在家里使用 hp 9000 系统,而且你们中的大多数人实际上会接近家庭系统的容量。例如,大多数用户在他们的系统中没有超过 16 Gb 的内存。当然,一些休闲游戏玩家每个月都会使用工作站玩一次游戏,但我敢打赌,这个比例非常小。因此,脚踏实地意味着我将在 8 Gb 64 位系统上解决堆空间不超过 512 mb 的问题,或者如果您过度使用 1 Gb。我很确定即使这些数字纯粹是矫枉过正。我一直在游戏期间监控内存使用情况,看看寻址是否会产生任何影响,但当我处理低得多或大得多的值时,我根本没有注意到任何差异。即使在服务器/工作站上,无论我设置多大的值,性能都没有明显变化。这并不是说一些 jave 用户可能能够利用更多的空间寻址,但到目前为止,我还没有看到任何需要这么多的应用程序。当然,我假设如果 java 实例用完足够的堆空间来使用它们,它们的性能差异会很小。到目前为止,我还没有发现任何一个,但是如果你设置了太多的堆空间,缺乏真正安装的内存会立即显示性能下降。当你有一个 4 Gb 系统时,你会很快耗尽堆空间,然后你会看到一些错误和减速,因为人们处理了太多实际上在系统中没有空闲的空间,所以操作系统开始处理驱动器空间以弥补短缺因此它开始交换。但是,如果您设置了太多堆空间,则缺少实际安装的内存会立即显示性能下降。当你有一个 4 Gb 系统时,你会很快耗尽堆空间,然后你会看到一些错误和减速,因为人们处理了太多实际上在系统中没有空闲的空间,所以操作系统开始处理驱动器空间以弥补短缺因此它开始交换。但是,如果您设置了太多堆空间,则缺少实际安装的内存会立即显示性能下降。当你有一个 4 Gb 系统时,你会很快耗尽堆空间,然后你会看到一些错误和减速,因为人们处理了太多实际上在系统中没有空闲的空间,所以操作系统开始处理驱动器空间以弥补短缺因此它开始交换。

于 2019-10-15T18:30:53.860 回答