我试图像这样增加我的堆内存:
-Xmx9g -Xms8g
老实说,只是因为我可以。

现在我想知道,为什么 JVM 不使用更多它,并且不那么频繁地安排 GC。

系统:
JVM:Java HotSpot(TM) 64 位服务器 VM(24.51-b03,混合模式)
Java:版本 1.7.0_51,供应商 Oracle Corporation

编辑:
我想改进建模过程的配置(吞吐量优于响应能力)。

最佳答案

Java 1.7 separates the heap into a few spaces 中的 HotSpot JVM,与本次讨论相关的有:

  • 伊甸园,新对象所在的地方
  • Survivor,在 Eden 被 GC 处理后,如果需要对象,它们会去哪里

  • 当您分配一个新对象时,它只是简单地附加到 Eden 空间中。一旦伊甸园满了,它就会被清理成所谓的“小 Collection ”。伊甸园中仍可访问的对象被复制到幸存者,然后伊甸园被删除(从而收集所有未被复制的对象)。

    你想要的是填满 Eden,而不是整个堆。

    例如,以这个简单的应用程序为例:
    public class Heaps {
      public static void main(String[] args) {
        Object probe = new Object();
        for (;;) {
          Object o = new Object();
          if (o.hashCode() == probe.hashCode()) {
            System.out.print(".");
          }
        }
      }
    }
    
    probe 只是为了确保 JVM 不能优化掉循环;重复的 new Object() 正是我们所追求的。如果您使用默认的 JVM 选项运行它,您将获得与您所看到的类似的图表。对象在 Eden 上分配,这只是整个堆的一小部分。一旦 Eden 已满,它就会触发一个小收集,它会清除所有这些新对象并将堆使用率降低到其“基线”,接近于 0。

    那么,如何填满整个堆呢?设置伊甸园很大! Oracle 发布了它的 heap tuning parameters ,这里相关的两个是 -XX:NewSize-XX:MaxNewSize 。当我用 -Xms9g -XX:NewSize=8g -XX:MaxNewSize=8g 运行上面的程序时,我得到了更接近你预期的东西。

    在一次运行中,这几乎耗尽了所有堆,以及我指定的所有 Eden 空间;后续运行只占用了我指定的伊甸园的一小部分,如您所见。我不太确定这是为什么。

    VisualVM 有一个名为 Visual GC 的插件,可让您查看有关堆的更多详细信息。这是我的屏幕截图,在正确的时刻拍摄,显示 Eden 几乎已满,而旧空间几乎是空的(因为循环中的那些 new Object() 都没有在 Eden 集合中幸存下来)。

    关于java - 为什么JVM不使用更多的堆内存,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24137280/

    10-13 04:29