我试图像这样增加我的堆内存:-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,与本次讨论相关的有:
当您分配一个新对象时,它只是简单地附加到 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/