它isnotpossible增加VM启动后Java堆的最大大小。这是什么技术原因?垃圾收集算法是否依赖于具有固定数量的内存来处理?还是出于安全原因,通过消耗所有可用内存来阻止Java应用程序DOS系统上的其他应用程序?为什么Java堆的最大大小是固定的?
回答
在Sun的JVM,最后我就知道,整个堆必须在连续的地址空间进行分配。我认为,对于大堆值,在启动后添加到地址空间非常困难,同时确保它保持连续。你可能需要在启动时获得它,或者根本不需要。因此,它是固定的。
即使它不是全部立即使用,为整个堆的地址空间在启动时保留。如果它不能为您传递的-Xmx的值保留足够大的连续地址空间块,则它将无法启动。这就是为什么在32位Windows上分配大于1.4GB的堆是很困难的 - 因为很难找到这种大小或更大的连续地址空间,因为某些DLL喜欢在某些地方加载,分割地址空间。因为地址空间非常多,所以当你使用64位时,这并不是一个问题。
这几乎肯定是出于性能的考虑。我无法找到一个很好的链接,详细说明这进一步,但这里是从彼得·凯斯勒一个相当不错的报价(full link - 一定要阅读注释),我发现搜索时。我相信他在Sun的JVM上工作。
我们需要为堆的连续存储器 区域的原因是,我们有一个 一束被 索引由(缩放)偏移量从 开始堆的侧的数据结构。例如,我们 跟踪与 “卡片标记阵列”,其具有用于每个512个字节堆的一个字节 对象引用的更新。当我们 存储在堆的参考,我们有 来标记 卡片标记阵列中的对应字节。我们右移商店的 目的地址和 使用该索引卡片标记阵列。 趣味算术解决游戏中,你 不能用Java做,你去(有 在C :-)发挥++。
这是在2004年 - 我不确定自那时以来发生了什么变化,但我确信它仍然成立。如果你使用像Process Explorer的一个工具,你可以看到,虚拟大小(添加虚拟大小和私人大小的内存列)的Java应用程序包括从启动点的总堆大小(加上其他所需的空间,毫无疑问) ,即使在过程中“拿来主义”将是没有在附近直到堆开始填满记忆...
我认为这个简短而尖锐的答案是因为Sun没有发现开发它所花费的时间和成本。
对于这样的功能,最引人注目的用例就是桌面上的IMO和Java,在启动JVM的机制方面,Java一直是桌面上的灾难。我怀疑那些最关心这些问题的人倾向于将重点放在服务器端,并查看最好留给本地包装的其他细节。这是一个不幸的决定,但它应该是决定应用程序的正确平台时的决定点之一。
如果你可以成长,一个非常合理的要求也能够缩小,而Sun JVM真的不喜欢放弃内存。 Microsoft JVM可以使用系统中的所有内存。 – 2010-01-21 15:32:03
@托尔比约恩Ravn的安德森,它既可以收缩,虽然这是一个有点最近和不良记录的能力(以及一些在桌面上真的糟糕到已丢失)。请参阅-XX:MaxHeapFreeRatio和-XX:MinHeapFreeRatio http://stackoverflow.com/questions/763295/setting-jvm-heap-size-at-runtime/763305#763305 – Yishai 2010-01-21 16:03:22
未记录的XX选项不计数:) – 2010-01-21 16:58:27
我的直觉是,它与内存管理相关的操作系统上运行的其他应用程序。
如果将最大堆大小设置为(例如)框上的RAM数量,您可以有效地让VM确定需要多少内存(达到此限制)。问题在于虚拟机可能会有效地削弱正在运行的机器,因为它会在决定需要垃圾收集之前接管机器上的所有内存。
当您指定最大堆大小时,您对VM所说的内容是,在您需要开始垃圾收集之前,您可以使用此内存量。你不能有更多,因为如果你采取更多的话,那么运行在盒子上的其他应用程序将会减速,如果你使用的不止这些,你将开始交换到磁盘。
另请注意,它们是关于内存的两个值,即“当前堆大小”和“最大堆大小”。当前堆大小是堆大小当前使用的内存大小,如果需要更多,它可以调整堆大小,但不能将堆大小调整为大于最大堆大小值。
我认为是服务器,那里有一个管理员在一个晴朗的答案谁了解如何调整JVM(或者至少您可以合理预期这一点)并设置适当的最大值以便与其他进程一起使用。然而,在桌面上你问一个用户去鼓捣配置文件和启动脚本,他们有没有经验或理解的东西,和Sun目前的答案是 - 用C编写 – Yishai 2010-01-21 15:11:07
@Yishai一个发射器:太阳VM默认对于大多数应用程序来说相当合理的值,iirc的默认值也会根据可用RAM进行调整。对于默认值有问题的应用程序,安装脚本可以很容易地创建一个启动脚本(不是c启动程序),它可以设置另一个最大值。编辑:顺便说一句,我也不喜欢它,我相信如果他们想要,Sun可以删除它。 – Fredrik 2010-01-21 16:17:22
@Fredrik,如果用户安装脚本后增加RAM他们的系统上运行?某些桌面应用程序希望在可用时使用更多可用RAM(例如,用于缓存)。 – Yishai 2010-01-21 18:36:08
从IBM的performance tuning tips(因此可能无法直接适用于Sun的虚拟机)
Java堆参数会影响垃圾收集行为。增加堆大小支持更多的对象创建。因为大堆需要更长的时间才能填充,所以在垃圾收集发生之前应用程序运行的时间会更长。然而,更大的堆也需要更长的时间来压缩并导致垃圾回收花费更长时间。
JVM具有用于管理JVM存储的阈值。达到阈值时,会调用垃圾回收器来释放未使用的存储。因此,垃圾收集可能会导致Java性能的显着下降。在更改初始和最大堆大小之前,应考虑以下信息: 在大多数情况下,应将最大JVM堆大小设置为高于初始JVM堆大小的值。这允许JVM在初始堆的范围内的正常稳定状态期间有效地操作,而且通过将堆扩展到最大JVM堆大小来在高事务量期间有效操作。在某些需要绝对最优性能的罕见情况下,您可能需要为初始堆大小和最大堆大小指定相同的值。这将消除JVM需要扩展或收缩JVM堆大小时发生的一些开销。确保区域足够大以容纳指定的JVM堆。 小心使初始堆大小过大。尽管大堆大小最初通过延迟垃圾回收来提高性能,但大堆大小最终会影响响应时间,因为垃圾收集最终会启动,因为收集过程需要更多时间。
所以,我猜你不能在运行时更改值的原因是因为它可能没有帮助:或者你的堆有足够的空间,或者你没有足够的空间。一旦用完,GC循环将被触发。如果这样不能释放空间,那么无论如何你都塞满了。您需要捕捉OutOfMemoryException,增加堆大小,然后重试您的计算,希望这次您有足够的内存。
一般来说,除非你需要它,所以,如果你认为你可能需要扩大在运行时内存,你可以只指定一个较大的最大堆大小VM将不使用的最大堆大小。
我承认这有点不尽人意,似乎有点懒,因为我可以想象一个合理的垃圾收集策略,当GC未能释放足够空间时会增加堆大小。尽管我的想象力转化为高性能的GC实现是另一个问题,但是;)
历史上一直存在这种限制的原因,它不允许Applets在浏览器中吃掉所有用户的内存。从来没有这种限制的微软VM实际上允许这样做,这可能导致对用户计算机的某种拒绝服务攻击。仅在一年前,Sun在1.6.0 Update 10 VM中引入了一种让applet指定他们需要多少内存(限于物理内存的某个固定份额)的方法,而不是在计算机上始终将其限制为64MB有8GB或更多的可用。
现在,由于JVM已经发展,当虚拟机没有在浏览器中运行时,应该有可能摆脱这种限制,但即使存在大量错误报告,Sun显然从未认为它是如此高优先级的问题已经提交最终允许堆增长。
你是对的,也有错误报告要求是:http://bugs.sun.com/view_bug.do?bug_id=4741914,http://bugs.sun.com/view_bug.do?bug_id=4408373 – 2010-01-21 16:29:28
+1这是唯一对我有意义的答案,包括链接问题的答案。只需花上几个小时追逐与Crashplan一个问题,简单的修复是次数增加只是一个不起眼的参数,在一个不起眼的设置文件。谁选择了256MB的上限,让我的备份失败了几周而没有注意到,并且拥有充足的系统内存。 – 2014-09-20 12:38:53
- 1. 固定大小堆栈Java
- 2. 1.为什么堆栈内存的大小是固定的?
- 3. 为JBoss指定最佳的最小和最大堆大小
- 4. 什么是最大的SQL表大小
- 5. Java:什么决定了linux机器中可能的最大堆大小
- 6. Nexus的最大堆大小?
- 7. 创建固定大小的堆栈
- 8. 为什么gulp抱怨超过最大调用堆栈大小?
- 9. 预留Java JVM最大堆大小
- 10. java集最大堆栈大小
- 11. 堆中Java最大对象大小
- 12. 为什么要减小Java JVM线程堆栈的大小?
- 13. 有什么办法可以创建Java Util栈的固定堆栈大小
- 14. 的Java堆大小
- 15. java堆设置中的最大堆大小的限制
- 16. 在Java中创建最大线程的因素是什么,堆大小与最大线程数成反比?
- 17. 为什么你需要指定Java堆大小?
- 18. Hotspot JVM的“Xss”选项是否将固定的“初始堆栈大小”或堆栈可以增长到的“最大堆栈大小”设置为?
- 19. 最大堆大小无效
- 20. 为什么ArrayList的最大数组大小是Integer.MAX_VALUE - 8?
- 21. 固定大小的FIFO队列的正确术语是什么?
- 22. Java进程占用的内存大于其最大堆大小
- 23. 什么是安全堆大小?
- 24. iphone os支持的最大堆大小和堆栈大小是多少?
- 25. 固定大小
- 26. 为什么堆栈大小有限制?
- 27. C++最大std :: string的长度是由堆栈大小还是堆大小决定的?
- 28. 是.htacess大小减少网站的性能?什么是.htacess的最大大小?
- 29. 什么是MySQL的最佳varchar大小?
- 30. 什么是Resourcestring最大大小和最大数量限制?
类似的问题:“为什么(星期日)JVM对内存使用一个固定的上限( -Xmx)?” - http://stackoverflow.com/questions/3358328/why-does-the-sun-jvm-have-a-fixed-upper-limit-for-memory-usage-xmx – sleske 2012-02-28 12:24:14