【问题标题】:Why does Java use a static heap rather than allow an arbitrary amount of memory?为什么 Java 使用静态堆而不是允许任意数量的内存?
【发布时间】:2014-05-06 18:30:49
【问题描述】:

在 Java 中,虚拟机预先分配了一个在运行时无法扩展的内存堆。开发人员可以在 VM 加载时使用 -Xmx 开关增加堆的大小,但无法在运行时增加堆的最大大小。这是为什么呢?

【问题讨论】:

    标签: java memory jvm heap-memory vm-implementation


    【解决方案1】:

    碎片是内存分配中的一个大问题,内存不足也是如此。如果您可以分配和保留所需的内存,尤其是在服务器环境中,它会简单得多,并且不易出错。通过预分配内存,您也更有可能将大部分内存连续分配(不能保证,谢谢@mttdbrd),这可以更快地访问。

    回到 Java 刚开始的时候,内存超过 1GB 的安装几乎是闻所未闻的,相反,我们不得不使用内存低至 256mb 的机器,有时甚至更少!再加上 RAM 的速度有多慢,能够读写希望连续分配的块就更有意义了。您也不会不断地敲击操作系统以提供更多 RAM,然后再次释放它,从而释放(当时)宝贵的 CPU 周期。

    在那种环境下,内存很容易突然用完,因此能够分配您可能需要的内容并确保您在时机成熟时拥有它是很有意义的。

    这些天来,我想随着 RAM 更容易访问,它变得不那么有意义了,但是,当我查看我的服务器以及内存分配方式时,我喜欢我所有的 Java 应用程序都很好的事实,主要是与遍布各处的其他一些应用程序相比,它是连续分配的内存块。

    这也是为什么你不能在运行时增加堆的原因,没有办法保证你将有一个连续的分配。

    【讨论】:

    • 我不明白为什么只要有足够大的内存可用,就不允许开发人员在运行时扩展堆。
    • JVM 规范非常清楚堆中的内存不需要是连续的。您可能希望它是这样,但甚至不能保证在 JVM 启动时内存是连续的。请参阅 JVM 规范 2.5.3。
    • @TylerDurden 内存可用但不连续,因此会影响性能
    • @mttdbrd - 这当然是真的,我的回答在这一点上太模糊了,我会马上修改。感谢您指出这一点。
    • “没有办法保证你将有一个连续的分配”——我不明白为什么这是真的。如果我有300M的堆,想扩容到600M,我就分配600M,把300M复制到新600M的开头,释放旧的300M,那么600M就是我新的扩展堆。我不明白为什么不支持这样做。
    【解决方案2】:

    根据 JVM 规范,没有理由必须提前指定堆大小,除非它是实现者的选择。该规范指出:“Java 虚拟机实现可以为程序员或用户提供对堆初始大小的控制,以及,如果堆可以动态扩展或收缩,则可以控制最大和最小堆大小。”

    这里的其他答案是错误的:“堆可能是固定大小的,或者可以根据计算需要扩展,如果不需要更大的堆,可能会收缩。”

    来源:Java 虚拟机规范,Java SE 7 版。第 2.5.3 节,“堆”。这是印刷版的第 13 页。

    【讨论】:

      【解决方案3】:

      当您的代码开始工作时,JVM 已经创建并配置好了。此外,此限制保证程序不会占用所有可用的系统资源,从而破坏服务器上其他应用程序的正常功能,无论其代码有多糟糕。 ;)

      【讨论】:

      • 规范对此毫不含糊:堆可以动态调整大小。这个答案是不正确的。
      • @mttdbrd,堆可以动态调整大小,当然,但不是最大堆大小。据我了解,问题是关于最大堆大小。
      • 没有。规范说它可以动态扩展。规范中对堆大小没有限制。请参阅我的回答:“堆可能具有固定大小或可以根据需要扩展......”。固定堆大小是 Sun (Oracle) JVM 的实现细节,而不是规范强加的要求。基本上,它是使用功能区而不是菜单栏的 Microsoft Word 之类的实现细节。他们这样做的“原因”我们无法理解。 OP 提出的问题是为什么?请参阅上面的问题。
      • @mttdbrd,他问:“......没有办法在运行时增加堆的最大大小。这是为什么呢?”所以它大约是最大尺寸,不是吗?在您的引文中,“堆可能是固定大小的,或者可以根据计算的需要进行扩展,并且如果不再需要更大的堆,则可能会收缩”作者讲述了堆大小的动态变化。它是在 JVM 中实现的——内存是动态变化的,但是这些变化受到不能动态改变的最小和最大限制的限制。所以这不是一个答案。无论如何,让我们尝试提供更好的答案,而不是寻找更糟糕的答案。
      猜你喜欢
      • 2016-12-28
      • 1970-01-01
      • 1970-01-01
      • 2011-01-28
      • 2021-10-01
      • 1970-01-01
      • 2013-03-13
      • 2011-12-11
      相关资源
      最近更新 更多