JVM最大堆大小可以动态吗?

JVM -Xmx参数允许将JVM的最大堆大小设置为某个值。 但是,有没有办法让这个价值变得有活力? 换句话说,我想告诉JVM“看看,如果你需要它,只需继续从系统中取RAM,直到系统出来。”

问题的两个部分:首先,有问题的应用程序可以使用非常广泛的ram,具体取决于用户正在做什么,因此概念性最小值和最大值相差很远。 其次,JVM似乎在启动时保留虚拟内存的最大堆空间。 这个特定的应用程序运行在各种各样的硬件上,因此选择“一刀切”的最大堆空间很难,因为它必须足够低才能在低端硬件上运行,但我们真的喜欢能够利用真正强劲的机器,如果它们可用的话。

但是,有没有办法让这个价值变得有活力?

从字面上看,没有。 最大堆大小设置为JVM启动时间,无法增加。

实际上,您可以将最大堆大小设置为平台允许的最大大小,并让JVM根据需要扩展堆。 这样做有明显的风险; 即您的应用程序使用所有内存并导致用户的计算机停止运行。 但是这个风险隐含在你的问题中。

编辑

值得注意的是,有各种-XX... GC调整选项,允许您调整JVM扩展堆的方式(最多)。

另一种可能性是将您的应用程序分成两部分。 该应用程序的第一部分完成了确定问题“大小”所需的所有准备工作。 然后它计算出适当的最大堆大小,并在新的JVM中启动应用程序的第二部分内存。

  • 这仅在应用程序可以如上所述明智地进行分区时才有效。

  • 这仅在可以计算问题大小时才有效。 在某些情况下,计算问题大小等于计算结果。

  • 目前尚不清楚您将获得比仅仅让堆增长到最大大小更好的整体性能。

它没有。 它可能,也可能应该:

 -Xmx90% // 90% of physical memory 

但是,默认隐含的100%可能不是一个好主意。

用非GC语言编写的程序非常勤奋地管理它的内存,它会尽快修剪任何垃圾。 允许它获取它请求的任何内存是有意义的,假设它负责迅速的垃圾处理。

GC语言不同。 它只在必要时收集垃圾。 只要有空间,它就不在乎周围的垃圾徘徊。 如果它可以获得它想要的所有内存,它将获得计算机中的所有内存。

因此,GC程序员不必再担心处理每一块垃圾,但他仍然必须对可容忍的垃圾/活动对象比率有一个大概的了解,并指示GC使用-Xmx。

基本上,你不能使用纯Java来适应各种用户的硬件:那就是当一些shell /批处理脚本可以派上用场时。

我在OS X和Linux上做到了这一点:我有一个小的bash shell脚本,负责根据运行应用程序的硬件找到正确的JVM参数,然后调用JVM。

请注意,如果您要提供桌面Java应用程序,那么您可能希望使用类似izpack的东西来为您的用户提供安装程序:

http://izpack.org

我根本不知道Java Web Start是否可以用来提供不同的JVM参数,具体取决于用户的配置(可能不是,如果你计划提供一个专业的桌面应用程序,JWS真的很不错。)