【发布时间】:2014-05-06 18:30:49
【问题描述】:
在 Java 中,虚拟机预先分配了一个在运行时无法扩展的内存堆。开发人员可以在 VM 加载时使用 -Xmx 开关增加堆的大小,但无法在运行时增加堆的最大大小。这是为什么呢?
【问题讨论】:
标签: java memory jvm heap-memory vm-implementation
在 Java 中,虚拟机预先分配了一个在运行时无法扩展的内存堆。开发人员可以在 VM 加载时使用 -Xmx 开关增加堆的大小,但无法在运行时增加堆的最大大小。这是为什么呢?
【问题讨论】:
标签: java memory jvm heap-memory vm-implementation
碎片是内存分配中的一个大问题,内存不足也是如此。如果您可以分配和保留所需的内存,尤其是在服务器环境中,它会简单得多,并且不易出错。通过预分配内存,您也更有可能将大部分内存连续分配(不能保证,谢谢@mttdbrd),这可以更快地访问。
回到 Java 刚开始的时候,内存超过 1GB 的安装几乎是闻所未闻的,相反,我们不得不使用内存低至 256mb 的机器,有时甚至更少!再加上 RAM 的速度有多慢,能够读写希望连续分配的块就更有意义了。您也不会不断地敲击操作系统以提供更多 RAM,然后再次释放它,从而释放(当时)宝贵的 CPU 周期。
在那种环境下,内存很容易突然用完,因此能够分配您可能需要的内容并确保您在时机成熟时拥有它是很有意义的。
这些天来,我想随着 RAM 更容易访问,它变得不那么有意义了,但是,当我查看我的服务器以及内存分配方式时,我喜欢我所有的 Java 应用程序都很好的事实,主要是与遍布各处的其他一些应用程序相比,它是连续分配的内存块。
这也是为什么你不能在运行时增加堆的原因,没有办法保证你将有一个连续的分配。
【讨论】:
根据 JVM 规范,没有理由必须提前指定堆大小,除非它是实现者的选择。该规范指出:“Java 虚拟机实现可以为程序员或用户提供对堆初始大小的控制,以及,如果堆可以动态扩展或收缩,则可以控制最大和最小堆大小。”
这里的其他答案是错误的:“堆可能是固定大小的,或者可以根据计算需要扩展,如果不需要更大的堆,可能会收缩。”
来源:Java 虚拟机规范,Java SE 7 版。第 2.5.3 节,“堆”。这是印刷版的第 13 页。
【讨论】:
当您的代码开始工作时,JVM 已经创建并配置好了。此外,此限制保证程序不会占用所有可用的系统资源,从而破坏服务器上其他应用程序的正常功能,无论其代码有多糟糕。 ;)
【讨论】: