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

问题描述 投票:23回答:3

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

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

java memory jvm
3个回答
11
投票

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

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

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

编辑

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

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

  • 这仅在应用程序可以如上所述明智地进行分区时才有效。
  • 这仅在可以计算问题大小时才有效。在某些情况下,计算问题大小等于计算结果。
  • 目前尚不清楚您将获得比仅仅让堆增长到最大大小更好的整体性能。

7
投票

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

-Xmx90%  // 90% of physical memory

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

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

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

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


3
投票

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

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

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

http://izpack.org

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


1
投票

有一个JDK增强建议(JEP)8204088

“动态最大内存限制”

这表明要引入CurrentMaxHeapSize:

为了动态限制提交的内存(即堆大小)可以增长的大小,引入了一个新的动态用户定义变量:CurrentMaxHeapSize。此变量(以字节为单位)限制了可以扩展堆的大小。它可以在启动时设置并在运行时更改。无论何时定义,它必须始终具有等于或低于MaxHeapSize的值(Xmx - 限制堆可以增长的启动时间选项)。与MaxHeapSize不同,CurrentMaxHeapSize可以在运行时动态更改。

预期的用法是使用非常保守的Xmx值设置JVM(显示对内存占用的影响非常小),然后使用CurrentMaxHeapSize动态限制控制堆的大小。

虽然没有迹象表明这个功能正在积极地工作,但它是相对较新的JEP(从2018年开始),所以我仍然会记住这一点。

公司Jelastic(jelastic.com)为G1垃圾收集器制作了JEP 8204088的工作原型:

请参阅http://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2018-May/022077.html上的说明和OpenJDK http://cr.openjdk.java.net/~tschatzl/jelastic/cmx/的补丁列表

© www.soinside.com 2019 - 2024. All rights reserved.