java - 为什么 JVM 不使用更多的堆内存

标签 java garbage-collection jvm

我试过像这样增加堆内存:

-Xmx9g -Xms8g

老实说,只是因为我可以。

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

Heap Usage Graph

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

编辑:
我想改进我的建模过程配置(吞吐量胜过响应速度)。

最佳答案

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

  • 伊甸园,新事物的归宿
  • Survivor,在 Eden 被 GC 后,如果需要的话,对象会去哪里

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

您想要填满 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 运行上述程序时,我得到的结果更接近您的预期。

enter image description here

在一次运行中,这几乎用完了所有堆,以及我指定的所有 Eden 空间;随后的运行只占用了我指定的 Eden 的一小部分,如您在此处所见。我不太清楚这是为什么。

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

enter image description here

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

相关文章:

java - 轴2迁移

java - 无法在 jasperviewer 中以 .html 以外的格式保存报告

c# - 应该以什么顺序释放 COM 对象和垃圾收集?

java - 为什么在记录、生产者和消费者数量不变的 Kafka 经纪人中 GC 时间会增加?

java - 如何在不使用任何工具的情况下查找 Java 应用程序中 Activity 对象的数量?

java - 如何在spring mvc中用逗号分隔另一个字符串中的每个声明的字符串?

java - 如何使用 Canvas 进行缩放

java - Java中通过finalize()函数测试垃圾回收,是活的还是死的?

java - 捕获内存不足错误之前的最后一个进程

java - 缺少内存 : size of young generation includes only one survivor space