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

时间:2012-11-25 09:32:07

标签: java oop optimization compression

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

由于       比涅斯

5 个答案:

答案 0 :(得分:17)

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

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

有一个有趣的事实:一旦超过这个32 GiB边界,JVM将停止使用压缩对象指针,从而有效地减少了可用内存。这意味着将JVM堆增加到32 GiB以上,你必须超越它。根据伟大的Everything I Ever Learned about JVM Performance Tuning @twitter(大约13:00)演示文稿将堆从32 GiB增加到48 GiB以下的任何内容实际上会减少可用内存量(!),因为压缩对象指针不再那里。

答案 1 :(得分:8)

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

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

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

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

  

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

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

答案 2 :(得分:3)

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

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

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

4GB * ObjectAlignmentInBytes

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

-XX:ObjectAlignmentInBytes=16

在文档中需要考虑更大的堆大小:

  

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

答案 3 :(得分:1)

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

  1. 不使用压缩的oops。
  2. 减少应用程序的内存消耗(内存分析器是调查内存使用情况的一个非常方便的工具)。
  3. 在多个JVM之间拆分工作负载,每个JVM都有一个32GB以下的堆。
  4. 以上每一项都有可能解决您的问题。哪个是最合适的,我们真的很难说。

      

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

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

答案 4 :(得分:1)

数据的本质究竟是什么?

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

有些图书馆可以帮助您实现这一目标,包括: