Java在Windows XP上的最大内存

我一直能够为运行在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可以识别。

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

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

或者,您可以切换到64位Windows和64位JVM。 尽管别人建议,尽管它会咀嚼更多的RAM,你将有更多的连续的虚拟地址空间,连续分配2GB将是微不足道的。

这与连续的内存有关。

以下是我在网上找到的一些信息 ,以前有人问,据说是来自“虚拟神”:

我们需要一个连续的堆内存区域的原因是,我们有一堆边数据结构,从堆的开始按(缩放)偏移索引。 例如,我们使用“卡标记数组”来跟踪对象引用更新,每个512字节的堆有一个字节。 当我们在堆中存储一个引用时,我们必须在卡片标记数组中标记相应的字节。 我们右移存储的目标地址,并使用它来索引卡片标记数组。 有趣的寻址算术游戏,你不能在Java中,你得到(必须:-)在C + +中玩。

通常情况下,我们并不难获得适度的连续区域(在Windohs上高达1.5GB,在Solaris上高达3.8GBYMMV)。 在Windohs上,问题主要是有一些库在JVM启动之前被加载,从而分割了地址空间。 使用/ 3GB开关不会重定义这些库,所以它们仍然是我们的问题。

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

Windows的Java堆大小限制是:

  • 32位Java上最大可能的堆大小: 1.8 GB
  • 建议在32位Java上使用堆大小限制: 1.5 GB (或者使用/ 3GB选项时为1.8 GB

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

可以处理非连续堆的Oracle JRockit在具有/ 3GB开关的Windows 2003 / XP上可以具有2.85 GB的Java堆大小。 看起来碎片对于Java堆的大小可能会有相当大的影响。

JVM需要连续的内存,并且依赖于还在运行的是什么,之前运行的是什么以及Windows如何管理内存,您可能能够获得高达1.4GB的连续内存。 我认为64位Windows将允许更大的堆。

Sun的JVM需要连续的内存。 所以可用内存的最大数量是由内存碎片决定的。 尤其是驱动程序的dll在加载到某个预定义的基址时往往会碎片化内存。 所以你的硬件和驱动程序决定你可以得到多少内存。

这两个来源与孙工程师的论述: 论坛 博客

也许另一个JVM? 你尝试过和谐吗? 我想他们打算让非连续的记忆。

我认为这与Windows的配置有很大关系: Java -Xmx Option

一些更多的测试:我能够在只有768MB物理RAM(加上虚拟内存)的旧式Windows XP机器上分配1300MB。 在我的2GB RAM机器上,我只能得到1220MB。 在其他各种公司计算机上(使用较旧的Windows XP),我能够获得1400MB。 这台机器的1220MB的限制是相当新的(刚刚从戴尔购买),所以也许它有更新的(和更臃肿的)Windows和DLL(它正在运行的Windows XP专业版2002 SP2)。

从(有限内存)virtuzzo VPS运行Java程序时,出现此错误消息。 我没有指定任何内存参数,并发现我必须明确设置一个数目,因为默认值必须太高。 例如-Xmx32m(显然需要根据您运行的程序进行调整)。

只是把这里,以防其他人得到上述错误信息,而不是像提问者那样指定大量的内存。

如果分配一个巨大的块,sun的JDK / JRE需要连续的内存量。

操作系统和初始应用程序倾向于在加载可用RAM的片段时分配比特和片段。 如果连续的块不可用,则SUN JDK不能使用它。 Bea的JRockit(被Oracle收购)可以分配内存。

每个人似乎都在回忆连续的记忆,却忽略了承认一个更紧迫的问题。

即使100%的连续内存分配,在32位Windows操作系统上也不能有2 GiB堆大小(默认情况下为*)。 这是因为32位Windows进程不能处理超过2 GiB的空间。

Java进程将包含perm gen(在Java 8之前),每个线程的堆栈大小,JVM /库开销(每个构建大大增加) ,除了堆之外

此外,JVM标志及其默认值在版本之间改变。 只要运行以下,你会得到一些想法:

  java -XX:+PrintFlagsFinal 

许多选项影响内存分割进出堆内。 留下你或多或少的2 GiB玩…

重用我的这个答案的部分内容(关于Tomcat,但适用于任何Java进程):

Windows操作系统将32位进程的内存分配限制为2 GiB(默认情况下)。

[只能]分配大约1.5GB的堆空间,因为还有其他内存分配给进程(JVM /库开销,perm生成空间等)。

为什么32位Windows强加了2 GB的进程地址空间限制,但是64位Windows强加了4GB限制?

其他现代操作系统[咳嗽Linux]允许32位进程使用4 GiB可寻址空间中的全部(或大部分)进程。

也就是说,可以配置64位Windows操作系统以将32位进程的限制增加到4 GiB(32位上的3 GiB):

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366778(v=vs.85).aspx

这里是如何增加分页大小

  1. 右键点击我的电脑—>属性—>高级
  2. 在表演部分单击设置
  3. 点击高级选项卡
  4. 在虚拟内存部分,点击更改。 它会显示你当前的分页大小。
  5. 选择硬盘空间可用的驱动器。
  6. 提供初始大小和最大大小…例如初始大小0 MB和最大大小4000 MB。 (尽可能多的要求)

首先,当你有4 GB的RAM时使用页面文件是没有用的。 Windows不能访问超过4GB(实际上,因为内存不足),因此不使用页面文件。

其次,地址空间分为2个,内核一半,用户模式一半。 如果你的应用程序需要更多的内存,请在boot.ini中使用/ 3GB选项(确保java.exe被标记为“大地址识别”(google了解更多信息)。

第三,我认为你不能分配完整的2 GB的地址空间,因为java在内部浪费了一些内存(对于线程,JIT编译器,VM初始化等)。 使用/ 3GB开关更多。