为什么设置-Xmx过高有时会导致JVM失败,即使有可用的RAM?

7
基本上我们注意到,在某些计算机上,设置JVM选项-Xmx(最大堆大小)有时会导致JVM无法初始化,即使系统上的RAM很充足。
例如,在一台4gb的计算机上,我们有-Xmx1024m会失败,但是-Xmx800m可以正常工作。我可以理解在1gb甚至2gb的计算机上,但是在4gb的计算机上,尤其是考虑到Windows、Linux等操作系统可以将RAM交换出去,为什么会失败呢?
我看到了很多线程和问题,都建议减少最大堆大小,但没有人能够解释为什么会失败,这才是我真正想要知道的。
另外,如何表达“尽可能地消耗内存,但不超过某个大小”?

快速搜索结果显示,用户惊讶地发现JVM允许他们设置“-Xmx”到TB级别,即使他们没有接近这么多的交换空间。请问您能分享一下您测试时使用的确切命令和JVM版本吗? - alf
@alf,请记住,-Xmx 设置的是最大堆大小,这只是虚拟地址空间保留范围的大小;只有在 -Xms 中指定的量实际上由已提交的存储支持。例如,请参阅VirtualAlloc,并比较 MEM_RESERVEMEM_COMMIT 标志。 - Jeffrey Hantin
@JeffreyHantin 我确实关心,Jeffrey。这就是为什么我问OP到底做了什么。 - alf
Oracle的JDK 6。但我想更好的问题是如何说“尽可能多地占用内存”? - Stephane Grenier
@StephaneGrenier 标准JRE无法通过分配新的地址空间自动增加堆大小 - 它必须预先分配整个堆地址范围-Xmx值),但只有在需要时才将实际的RAM和/或交换页面映射到该地址空间中(从-Xms值开始)。这是一种优化导致的实现限制 - 它允许垃圾收集器将整个Java堆视为单个巨大的数组。 - Jeffrey Hantin
2个回答

13
这可能是由于虚拟地址空间碎片化引起的。根据DLL的加载地址、线程堆栈位置、不可移动的本地内存分配、内核保留地址等因素,在32位进程中,可能无法为堆的最大潜在大小保留一个连续的1024MB地址范围。请注意,这取决于情况。

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接