问题

我总是能够为在32位Windows XP(Java 1.4,1.5和1.6)上运行的Java SE分配1400兆字节。

java -Xmx1400m ...

今天我在使用Java 1.5_16和1.6.0_07的新Windows XP机器上尝试了相同的选项并得到错误:

Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

通过反复试验,我可以在这台机器上分配1200兆字节。

任何想法为什么一台机器将允许1400和另一台只有1200?

编辑:该机器有4GB的RAM,大约3.5GB,Windows可以识别。


#1 热门回答(118 赞)

请记住,Windows具有虚拟内存管理,而JVM只需要在其地址空间中连续的内存。因此,在系统上运行的其他程序不一定会影响你的堆大小。什么会妨碍你加载到你的地址空间的DLL。不幸的是,在链接期间最小化DLL重定位的Windows中的优化使得更有可能存在碎片化的地址空间。除了通常的东西之外,可能会切入你的地址空间的东西包括安全软件,CBT软件,间谍软件和其他形式的恶意软件。差异的可能原因是不同的安全补丁,C运行时版本等。设备驱动程序和其他内核位有自己的地址空间(4GB 32位空间的另外2GB)。

你可以在JVM进程中执行DLL绑定,并尝试将DLL重新绑定到更紧凑的地址空间。不好玩,但如果你绝望......

或者,你可以切换到64位Windows和64位JVM。尽管其他人建议,虽然它会占用更多的RAM,但你将拥有更多连续的虚拟地址空间,并且连续分配2GB将是微不足道的。


#2 热门回答(49 赞)

这与连续的记忆有关。

Here's some info I found online以前有人问过,据说来自"虚拟神":

我们需要堆的连续内存区域的原因是我们有一堆辅助数据结构,它们从堆的起始位置(缩放)偏移量索引。例如,我们使用"卡标记数组"跟踪对象引用更新,每个512字节的堆有一个字节。当我们在堆中存储引用时,我们必须在卡片标记数组中标记相应的字节。我们右移商店的目的地地址并使用它来索引卡片标记数组。有趣的解决你不能用Java做的算术游戏(必须:-)在C中玩。通常我们在获得适度的连续区域方面没有问题(在Windohs上高达约1.5GB,在Solaris上高达约3.8GB.YMMV。)。在Windohs上,问题主要是在JVM启动之前有一些库被加载,从而破坏了地址空间。使用/ 3GB开关不会重新定义这些库,因此它们仍然是我们的问题。我们知道如何制作分块堆,但使用它们会有一些开销。与32位JVM中的大堆相比,我们对更快的存储管理有更多的要求。如果你真的想要大堆,请切换到64位JVM。我们仍然需要连续的内存,但是更容易进入64位地址空间。


#3 热门回答(19 赞)

Windows的Java堆大小限制是:

  • 32位Java上最大可能的堆大小:1.8 GB
  • 建议的32位Java堆大小限制:1.5 GB(或1.8 GB / 3GB选项)

这不会帮助你获得更大的Java堆,但现在你知道你不能超越这些值。


原文链接