我可以使用压缩oops多于32 GB的堆

我能理解,使用压缩oops,我们只能使用32 GB的RAM。 有没有什么可以通过分配2堆或其他什么来使用更多?

谢谢Vineeth

你不能有多个堆(你可以拥有多个JVM,这称为扩展而不是扩展)。

JVM使用压缩对象指针自动低于32 GiB的内存。 如果你理解它是如何工作的(从每个地址中删除最小的三位,因为它们总是由于内存对齐而为0),你就会明白你不能再进一步了。

有一个有趣的事实:一旦超过这个32 GiB边界,JVM将停止使用压缩对象指针,从而有效地减少了可用内存。 这意味着你的JVM堆增加到32 GiB以上,你必须超越。 据我所知,关于JVM性能调优@twitter (大约13:00)的所有内容, 从32 GiB到48 GiB以下的任何增加堆的表示实际上会减少可用内存量 (!),因为压缩对象指针不再存在。

如果您需要超过32 GB,我建议您考虑使用一些非堆内存。 这有效地为您提供了额外的内存空间,不会占用太多堆。

例如,我经常使用200-800 GB,但只有1-2 GB的堆。 这意味着我拥有最有效的压缩Oopsforms和几乎无限的容量。 注意:有三种forms的压缩Oops,

  • 普通32位未移位(最高约2 GB)
  • 32位移位(最高约26 GB)
  • 32位移位和偏移(最大~32 GB)

使用off heap内存的两种方法是直接内存ByteBuffers和内存映射文件。 直接内存可以扩展到主内存大小的3/4左右。 内存映射文件可以很好地扩展到硬盘空间的大小(通常更多)

在这里,我已经应用了许多优化,使得最后80%的空间被参考而不是实际数据吃掉。

听起来你没有使用最有效的数据结构。 您可以使用不同的数据结构,其中数据更多是使用的空间或至少2 / 3rds。

您可以使用更大的堆大小和附加参数: -XX:ObjectAlignmentInBytes=alignment

此参数是Java对象的固定调整。 默认值为8 (字节)。 指示值必须是2的幂,范围从8256

堆大小限制(以字节为单位)计算如下:

 4GB * ObjectAlignmentInBytes 

64GB堆大小可用于具有以下行的压缩指针:

 -XX:ObjectAlignmentInBytes=16 

尽管如此,在文档中需要考虑更大的堆大小:

注意:随着对齐值的增加,对象之间未使用的空间也会增加。 因此,您可能没有意识到使用具有大型Java堆大小的压缩指针会带来任何好处。

如果我在你的鞋子里,我会调查以下各项:

  1. 不使用压缩的oops。
  2. 减少应用程序的内存消耗(内存分析器是调查内存使用情况的一个非常方便的工具)。
  3. 在多个JVM之间拆分工作负载,每个JVM都有一个32GB以下的堆。

上述每一项都有可能解决您的问题。 哪个是最合适的,我们真的很难说。

80%的空间被引用而不是实际数据吃掉。

这听起来相当极端。 值得重新审视您的数据结构,重点是减少对象引用的数量。 我过去已经按照这些方针做了一些事情,但是在不知道你的问题和你当前使用的数据结构的情况下很难给出具体的建议。

数据的本质究竟是什么?

执行此操作的方法可能是将数据存储在Java堆中。 你可以通过获取一些堆外内存来实现这一点,通常使用直接的ByteBuffer ,然后以字节的forms将数据存储在其中。 这有各种优点; 对象可以非常紧凑地存储,你不需要有一个巨大的堆,并且垃圾收集器不会扫描对象。 缺点是复杂性和内存泄漏的风险。

有些图书馆可以帮助您做到这一点,包括: