有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JVM最大堆大小可以是动态的吗?

JVM-Xmx参数允许将JVM的最大堆大小设置为某个值。但是,有没有一种方法可以使这种价值动态化?换句话说,我想告诉JVM“看,如果你需要它,就从系统中取出RAM,直到系统退出。”

提问的两部分原因: 首先,所讨论的应用程序可以使用非常广泛的ram,这取决于用户正在做什么,因此概念上的最小值和最大值相差甚远。其次,JVM似乎在引导时从虚拟内存中保留了最大堆空间。这个特定的应用程序在各种各样的硬件上运行,因此选择“一刀切”的最大堆空间是很困难的,因为它必须足够低,才能在低端硬件上运行,但我们真的希望能够利用真正强大的机器(如果它们可用的话)


共 (4) 个答案

  1. # 1 楼答案

    它没有。它可以,而且可能应该:

    -Xmx90%  // 90% of physical memory
    

    然而,默认的隐式100%可能不是一个好主意

    用非GC语言编写的程序非常勤奋地管理其内存,它将尽快删除任何垃圾。假设它负责及时的垃圾处理,允许它获取它请求的任何内存是有意义的

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

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

  2. # 2 楼答案

    有一个JDK增强计划(JEP)8204088

    “动态最大内存限制”

    这建议引入CurrentMaxHeapSize

    To dynamically limit how large the committed memory (i.e. the heap size) can grow, a new dynamically user-defined variable is introduced: CurrentMaxHeapSize. This variable (defined in bytes) limits how large the heap can be expanded. It can be set at launch time and changed at runtime. Regardless of when it is defined, it must always have a value equal or below to MaxHeapSize (Xmx - the launch time option that limits how large the heap can grow). Unlike MaxHeapSize, CurrentMaxHeapSize, can be dynamically changed at runtime.

    The expected usage is to setup the JVM with a very conservative Xmx value (which is shown to have a very small impact on memory footprint) and then control how large the heap is using the CurrentMaxHeapSize dynamic limit.

    虽然没有迹象表明该功能正在积极使用, 这是一个相对较新的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. # 3 楼答案

    基本上,您无法使用纯Java来适应各种用户的硬件:这时一点shell/批处理脚本就可以派上用场了

    我在OSX和Linux上就是这么做的:我有一个小的bashshell脚本,它负责根据运行应用程序的硬件查找正确的JVM参数,然后调用JVM

    请注意,如果您提供的是桌面Java应用程序,则可能需要使用izpack之类的工具为用户提供安装程序:

    http://izpack.org

    我根本不知道Java Web Start是否可以根据用户的配置提供不同的JVM参数(可能不会,如果您计划提供一个外观专业的桌面应用程序,那么JWS真的会大显身手)

  4. # 4 楼答案

    But, is there a way to make that value dynamic?

    实际上,不是。最大堆大小是在JVM启动时设置的,不能增加

    实际上,您可以将最大堆大小设置为平台允许的最大值,并让JVM根据需要增加堆。这样做有明显的风险;i、 e.您的应用程序使用所有内存,并导致用户的机器停止运行。但你的问题中隐含着这种风险

    编辑

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

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

    • 只有当应用程序可以像上面那样合理地分区时,这才有效

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

    • 现在还不清楚,与让堆增长到最大大小相比,您是否会获得更好的总体性能