【问题标题】:Setting JVM heap size at runtime在运行时设置 JVM 堆大小
【发布时间】:2010-10-20 06:46:52
【问题描述】:

有没有办法从正在运行的 Java 程序中设置堆大小?

【问题讨论】:

  • 供参考,这里是热点的RFE:bugs.sun.com/bugdatabase/view_bug.do?bug_id=4408373

标签: java jvm runtime heap-memory


【解决方案1】:

根据http://www.dreamincode.net/forums/showtopic96263.htm,您不能在运行时执行此操作,但您可以生成具有不同堆大小的另一个进程。

【讨论】:

  • 也被称为背部巨大的疼痛。如果您正在使用大量内存,那么您最不想做的就是释放它,然后在另一个进程中重新加载它。当然,您不能让旧进程保持打开足够长的时间来传输数据,因为您使用 2 个进程占用更多内存只是为了进行传输。最好希望这次你猜对了,否则你会重新来过。
【解决方案2】:

您可以在启动应用程序时调整这些设置,但是一旦 JVM 启动并运行,这些值就无法更改。像这样的:

java -Xms32m -Xmx512m FooBar

会将最小堆大小设置为 32MB,将最大堆大小设置为 512MB。一旦设置了这些,就不能在运行的程序中更改它们。

【讨论】:

    【解决方案3】:

    没有。

    对于堆要求非常多变的应用,您可以使用-Xmx 将最大堆大小设置得非常高,并调整-XX:MaxHeapFreeRatio-XX:MinHeapFreeRatio,这样应用就不会挂在很多堆收缩时的内存(它使用默认设置执行此操作)。

    但请注意,当应用实际使用的内存变化剧烈且快速时,这可能会导致性能问题 - 在这种情况下,您最好将其挂在所有内存上,而不是仅将其返回给操作系统一秒钟后再次申领。您可能还想摆弄GC options 以确保 GC 不会留下太多无人认领的对象,当堆有很大的增长空间时,它往往会这样做,这会破坏目标希望堆大小适应应用程序的需求。

    【讨论】:

    • -XX:MaxHeapFreeRatio 默认值为 70。空闲比率是堆上未分配的空间量与总堆大小的比值。如果可用空间的百分比高于默认值 70%,jvm 将减小堆的大小以允许操作系统使用内存。
    • 这是可能的(我做了很多次),但问题是内存使用量可以上下跳动很多。它与实际的活动对象集不成比例,只是连续制作大量对象可能会导致堆爆炸。仅当您手动导致 GC 时它才会关闭。因此,您基本上必须在实际 RAM 中保留最大数量。我们确实需要一个动态更改最大堆大小的选项。
    【解决方案4】:

    如果我正确理解了您的问题,您正尝试在运行时 更改堆大小。我看不出有任何理由为什么这应该是可能的。使用-Xmx JVM 选项在启动 设置堆大小。我还建议您仅在绝对需要时设置-Xms 选项。此选项设置分配给 JVM 的初始头内存量。

    您应该知道您的应用程序在内存方面的行为。明智地设置-Xmx 的值。如果您的应用程序是某种服务器应用程序,您可以设置一个更高的值,否则会在您的选择与在客户端计算机上运行的其他可能的应用程序以及当然可用内存之间妥协。

    【讨论】:

    • 明智地设置值...是的,这是个好建议。但是考虑这种情况 - 您正在观察您的 prod 应用程序如何接近堆最大值,而您对此无能为力。是的,代码中存在泄漏......但首先我们需要在白天保持活力,然后我们会解决问题
    • 另请注意,这可能是您无法控制 VM 启动设置的小程序或其他类型的应用程序。这些情况会很好。我认为主要问题是,如果您能够更改此设置,您可能会遇到与安全相关的内存问题。
    【解决方案5】:

    大家的共识可能确实是这是不可能的,但我们应该查看 JVM 源代码,看看它是如何进行人体工程学控制的。如果 JVMTI 代理能够在线/在运行时调整堆/perm/tenured/new/&c 大小,那就太好了。

    这会做什么?它将允许代理根据性能或占用空间目标推断大小调整,这在将 JVM 迁移到云中时非常重要。

    【讨论】:

    • 这读起来像 JVM 功能请求而不是答案。 . .
    【解决方案6】:

    我问自己同样的问题。与上面的答案不同,我可以对 my 应用程序增加最大堆 JVM 大小做一些事情。如果应用程序是集群模式下的 Web 服务器,我可以启动一个更改了最小/最大堆大小的新实例,然后关闭初始实例。这在 GlassFish 中尤其简单,您将管理实例与 nodeAgent(应用服务器集群实例)JVM 分开。

    由于许多 JVM 应用程序都是 Web 应用程序,我认为值得保留在此博客中。

    【讨论】:

      【解决方案7】:

      您可以在启动时使用 -mx 选项(也称为 -Xmx)这是您应该需要的最大尺寸,因为您不需要将其设置为大于您需要的最大大小。

      但是,一种解决方法是让 main() 检查最大大小,如果最大大小不符合要求,则重新启动 java。即启动另一个 java 程序并死掉。

      【讨论】:

      • 这假设您事先知道您需要多少内存。这对于网络服务器/其他流式传输的东西来说很好,但是如果您正在分析数据(例如构建索引/寻找趋势),您需要预先知道您的数据将是什么,这是非常有限的
      • @Basic 你不需要知道你需要多少内存。 -Xmx 是 JVM 可以拥有的最大值,即程序应该因 OutOfMemoryError 而崩溃,而不是使用更多内存。这个最大值通常取决于你有多少内存,默认是主内存的 1/4。无论您将最大值设置为多少,JVM 都不会为“hello world”程序使用大量内存。
      • 假设您有一个进程并提前给它 50 gig 的内存,并且在运行期间通知大量 GC 正在进行,可能 56 GiB 会更好,如果没有,您将无法轻松重新启动程序做了很多重新计算...
      • @kap 因此最好将最大值设置为您希望程序失败而不是继续运行的级别。
      猜你喜欢
      • 2021-06-03
      • 2012-07-18
      • 1970-01-01
      • 2016-07-18
      • 1970-01-01
      • 2016-06-22
      • 1970-01-01
      • 2015-11-06
      • 1970-01-01
      相关资源
      最近更新 更多