13

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

谢谢 Vineeth

4

5 回答 5

25

您不能拥有多个堆(尽管您可以拥有多个 JVM,这称为向外扩展而不是向上扩展)。

JVM 自动使用低于 32 GiB 内存的压缩对象指针。如果您了解它的工作原理(从每个地址中删除最年轻的三位,因为由于内存对齐,它们始终为 0),您就会明白您无法走得更远。

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

于 2012-11-25T09:54:57.223 回答
9

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

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

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

使用堆外内存的两种方式是直接内存字节缓冲区和内存映射文件。直接内存可以扩展到大约主内存大小的 3/4。内存映射文件可以很好地扩展到您的硬盘空间大小(通常更多)

在这里,我应用了许多优化,最终 80% 的空间被引用而不是实际数据占用。

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

于 2012-11-25T11:04:25.473 回答
7

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

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

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

4GB * ObjectAlignmentInBytes

64GB 堆大小可用于压缩指针,如下行:

-XX:ObjectAlignmentInBytes=16

但是,对于较大的堆大小,需要考虑文档中的注释:

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

于 2016-03-14T10:06:17.760 回答
1

如果我站在你的立场上,我会调查以下各项:

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

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

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

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

于 2012-11-25T09:48:38.630 回答
1

数据的本质是什么?

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

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

于 2012-11-25T10:10:18.910 回答