java JVM最大堆大小可以是动态的吗?
JVM-Xmx参数允许将JVM的最大堆大小设置为某个值。但是,有没有一种方法可以使这种价值动态化?换句话说,我想告诉JVM“看,如果你需要它,就从系统中取出RAM,直到系统退出。”
提问的两部分原因: 首先,所讨论的应用程序可以使用非常广泛的ram,这取决于用户正在做什么,因此概念上的最小值和最大值相差甚远。其次,JVM似乎在引导时从虚拟内存中保留了最大堆空间。这个特定的应用程序在各种各样的硬件上运行,因此选择“一刀切”的最大堆空间是很困难的,因为它必须足够低,才能在低端硬件上运行,但我们真的希望能够利用真正强大的机器(如果它们可用的话)
# 1 楼答案
它没有。它可以,而且可能应该:
然而,默认的隐式100%可能不是一个好主意
用非GC语言编写的程序非常勤奋地管理其内存,它将尽快删除任何垃圾。假设它负责及时的垃圾处理,允许它获取它请求的任何内存是有意义的
GC语言是不同的。它只在必要时收集垃圾。只要有空间,它就不在乎垃圾在周围徘徊。如果它能得到它想要的所有内存,它就能得到计算机中的所有内存
因此,GC程序员不必再担心如何处理每一块垃圾,但他仍然需要对可容忍的垃圾/活动对象比率有一个大致的了解,并用-Xmx指示GC
# 2 楼答案
有一个JDK增强计划(JEP)8204088
“动态最大内存限制”
这建议引入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/
# 3 楼答案
基本上,您无法使用纯Java来适应各种用户的硬件:这时一点shell/批处理脚本就可以派上用场了
我在OSX和Linux上就是这么做的:我有一个小的bashshell脚本,它负责根据运行应用程序的硬件查找正确的JVM参数,然后调用JVM
请注意,如果您提供的是桌面Java应用程序,则可能需要使用izpack之类的工具为用户提供安装程序:
http://izpack.org
我根本不知道Java Web Start是否可以根据用户的配置提供不同的JVM参数(可能不会,如果您计划提供一个外观专业的桌面应用程序,那么JWS真的会大显身手)
# 4 楼答案
实际上,不是。最大堆大小是在JVM启动时设置的,不能增加
实际上,您可以将最大堆大小设置为平台允许的最大值,并让JVM根据需要增加堆。这样做有明显的风险;i、 e.您的应用程序将使用所有内存,并导致用户的机器停止运行。但你的问题中隐含着这种风险
编辑
值得注意的是,有各种
-XX...
GC调优选项,允许您调整JVM扩展堆的方式(最大化)另一种可能是将应用程序分为两部分。应用程序的第一部分完成了确定问题“大小”所需的所有准备工作。然后计算出适当的最大堆大小,并在新JVM中启动应用程序中内存不足的第二部分
只有当应用程序可以像上面那样合理地分区时,这才有效
只有在可以计算问题大小的情况下,这才有效。在某些情况下,计算问题大小等于计算结果
现在还不清楚,与让堆增长到最大大小相比,您是否会获得更好的总体性能