Windows XP 上的 Java 最大内存

2022-08-31 09:59:44

我总是能够为在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,Windows可以识别大约3.5GB。


答案 1

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

您可以尝试在 JVM 进程中遍历 DLL 绑定,并尝试将 DLL 的数据库重新定位到更紧凑的地址空间。不好玩,但如果你绝望了...

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


答案 2

这与连续记忆有关。

以下是我在网上找到的一些信息,有人之前问过这个问题,据说来自“VM上帝”:

我们需要堆的连续内存区域的原因是,我们有一堆侧数据结构,这些结构按堆开头的偏移量(缩放)编制索引。例如,我们使用“卡标记数组”跟踪对象引用更新,该数组每 512 个字节堆有一个字节。当我们在堆中存储引用时,我们必须在卡标记数组中标记相应的字节。我们右移存储的目标地址,并使用它来索引卡标记数组。解决您在Java中无法做到的算术游戏的乐趣(必须:-)在C++玩。

通常,我们获取适度的连续区域(Windohs上高达约1.5GB,Solaris上高达约3.8GB)时,我们没有问题。YMMV.)。在Windohs上,问题主要是在JVM启动之前加载了一些库,这些库会破坏地址空间。使用 /3GB 开关不会重定这些库的基值,因此它们对我们来说仍然是一个问题。

我们知道如何制作块堆,但是使用它们会有一些开销。与 32 位 JVM 中对较大堆的请求相比,我们对更快存储管理的要求更多。如果您确实想要大型堆,请切换到 64 位 JVM。我们仍然需要连续内存,但进入 64 位地址空间要容易得多。