JVM -Xmx参数允许将JVM的最大堆大小设置为某个值。但是,有没有办法让这个价值变得有活力?换句话说,我想告诉JVM“看看,如果你需要它,只需继续从系统中取RAM,直到系统出来。”
要求的两部分原因: 首先,有问题的应用程序可以使用非常广泛的ram,具体取决于用户正在做什么,因此概念性的min和max值相差很远。其次,JVM似乎在启动时保留虚拟内存的最大堆空间。这个特定的应用程序运行在各种各样的硬件上,因此选择“一刀切”的最大堆空间很难,因为它必须足够低才能在低端硬件上运行,但我们真的喜欢能够利用真正强劲的机器,如果它们可用的话。
答案 0 :(得分:11)
但是,有没有办法让这个价值充满活力?
从字面上看,没有。最大堆大小设置为JVM启动时间,无法增加。
实际上,可以将最大堆大小设置为平台允许的大小,并让JVM根据需要扩展堆。这样做有明显的风险;即您的应用程序将使用所有内存并导致用户的计算机停止运行。但是这个风险隐含在你的问题中。
修改强>
值得注意的是,有各种-XX...
GC调优选项允许您调整JVM扩展堆的方式(最多)。
另一种可能性是将您的应用程序分成两部分。应用程序的第一部分完成了确定问题“大小”所需的所有准备工作。然后它计算出适当的最大堆大小,并在新的JVM中启动应用程序的第二部分内存。
仅当应用程序可以按照上述方式进行合理分区时才有效。
仅在可以计算问题大小时才有效。在某些情况下,计算问题大小等于计算结果。
目前尚不清楚您的整体性能是否会让您的堆积增长到最大值。
答案 1 :(得分:7)
没有。它可能,而且可能应该:
-Xmx90% // 90% of physical memory
然而,默认的隐含,100%,可能不是一个好主意。
用非GC语言编写的程序非常勤奋地管理它的内存,它会尽快修剪任何垃圾。允许它获取它请求的任何内存是有意义的,假设它负责及时的垃圾处理。
GC语言不同。它只在必要时收集垃圾。只要有空间,它就不会在乎垃圾徘徊。如果它能够获得它想拥有的所有内存,它将获得计算机中的所有内存。
因此,GC程序员不必再担心处理每一块垃圾,但他仍然必须对可容忍的垃圾/活动对象比率有一个大概的了解,并使用-Xmx指示GC。
答案 2 :(得分:3)
基本上,你无法使用纯Java来适应各种用户的硬件:那就是一些shell /批处理脚本可以派上用场。
我在OS X和Linux上做到这一点:我有一个小的 bash shell脚本,负责根据运行应用程序的硬件找到正确的JVM参数然后调用JVM。
请注意,如果您要提供桌面Java应用程序,那么您可能希望使用类似izpack的东西为您的用户提供安装程序:
我根本不知道Java Web Start是否可以用来提供不同的JVM参数,具体取决于用户的配置(可能不是,如果你计划提供一个专业的桌面应用程序,JWS真的很不错)。
答案 3 :(得分: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/