Windows XP上的Java最大内存

时间:2008-10-05 00:02:04

标签: java windows memory

我总是可以为在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可识别。

13 个答案:

答案 0 :(得分:120)

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

可以尝试在你的JVM进程中浏览你的DLL绑定,并试着将你的DLL重新绑定到更紧凑的地址空间。没有趣,但如果你绝望......

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

答案 1 :(得分:50)

这与连续的记忆有关。

Here's some info I found online以前有人问这个,据说来自“虚拟神”:

  

我们需要连续记忆的原因   堆的区域是我们有的   一堆副数据结构   索引(缩放)偏移量   堆的开始。例如,我们   使用a跟踪对象引用更新   “卡标记数组”,有一个字节   对于每512个字节的堆。什么时候我们   在我们拥有的堆中存储引用   标记中的相应字节   卡片阵列。我们正确地转移了   商店的目的地址和   用它来索引卡片标记数组。   有趣的解决算术游戏你   不能用Java做的(有   to :-)在C ++中玩。

     

通常我们没有遇到麻烦   适度的连续区域(最多约   在Windohs上为1.5GB,在Solaris上高达约3.8GB。因人而异)。在Windohs,   问题主要是有一些问题   在之前加载的库   JVM启动时打破了   地址空间。使用/ 3GB开关   不会改变那些图书馆,所以他们   对我们来说仍然是一个问题。

     

我们知道如何制作大块的堆,但是   使用会有一些开销   他们。我们有更多的要求更快   存储管理比我们做的   32位JVM中更大的堆。如果你   真想要大堆,切换到   64位JVM。我们仍然需要连续   记忆,但更容易进入   一个64位的地址空间。

答案 2 :(得分:19)

Windows的Java堆大小限制为:

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

这无助于您获得更大的Java堆,但现在您知道您不能超越这些值。

答案 3 :(得分:10)

Oracle JRockit可以处理非连续堆,在Windows 2003 / XP上使用/ 3GB开关可以具有2.85 GB的Java堆大小。看来,碎片会对Java堆的大小产生很大的影响。

答案 4 :(得分:6)

JVM需要连续的内存,并且根据正在运行的内容,之前运行的内容以及Windows如何管理内存,您可以获得高达1.4GB的连续内存。我认为64位Windows将允许更大的堆。

答案 5 :(得分:6)

Sun的JVM需要连续的内存。因此,最大可用内存量由内存碎片决定。特别是当加载到某个预定义的基址时,驱动程序的dll会分散内存。因此,您的硬件及其驱动程序决定了您可以获得多少内存。

Sun的工程师发表声明的两个来源:forum blog

也许是另一个JVM?你试过Harmony吗?我认为他们计划允许非连续记忆。

答案 6 :(得分:3)

我认为它更多地与Windows的配置方式有关,如此响应暗示: Java -Xmx Option

更多测试:我能够在旧的Windows XP机器上分配1300MB,只有768MB的物理RAM(加上虚拟内存)。在我的2GB RAM机器上,我只能得到1220MB。在其他各种公司机器上(使用较旧的Windows XP),我能够获得1400MB。限制1220MB的机器非常新(刚刚从戴尔购买),因此它可能有更新(更臃肿)的Windows和DLL(运行Window XP Pro 2002 SP2)。

答案 7 :(得分:2)

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

如果其他人收到上述错误消息而没有像提问者那样指定大量内存,请将此放在此处。

答案 8 :(得分:1)

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

操作系统和初始应用程序倾向于在加载过程中分配位和碎片,从而分割可用的RAM。如果连续块不可用,则SUN JDK无法使用它。 Bea的JRockit(被Oracle收购)可以从片段中分配内存。

答案 9 :(得分:1)

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

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

Java进程将包含perm gen(pre Java 8),每个线程的堆栈大小,JVM /库开销(每次构建时都会增加)除堆之外的所有

此外,JVM标志及其默认值在不同版本之间变化。只需运行以下内容即可获得一些想法:

 java -XX:+PrintFlagsFinal

许多选项会影响堆内外的内存划分。让你或多或少地使用2 GiB玩......

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

  

Windows操作系统   将32位进程的内存分配限制为总共2 GiB(by   默认值)。

     

[您将只能]分配大约1.5 GiB堆   space,因为还有其他内存分配给进程   (JVM /库开销,perm gen space等。)。

     

Why does 32-bit Windows impose a 2 GB process address space limit, but 64-bit Windows impose a 4GB limit?

     

其他现代操作系统[咳嗽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

答案 10 :(得分:0)

以下是增加分页大小的方法

  1. 右键单击mycomputer --->属性--->高级
  2. 在效果部分点击设置
  3. 点击高级标签
  4. 在“虚拟内存”部分中,单击“更改”。它将显示当前的分页 尺寸。
  5. 选择硬盘空间可用的硬盘。
  6. 提供初始尺寸和最大尺寸......例如。初始大小0 MB和最大大小 4000 MB。 (尽可能多的要求)

答案 11 :(得分:0)

**有多种更改堆大小的方法,例如

  1. 文件->设置->构建,执行,部署->编译器,您将在其中找到堆大小
  2. 文件->设置->构建,执行,部署->编译器-> andriod ,在这里您还将找到堆大小。如果您遇到相同的问题,可以将其用于andriod项目。

对我有用的是

  1. 设置适当的适当JAVA_HOME路径,以防Java更新。

  2. 创建新系统变量计算机->属性->高级设置->创建新系统变量

名称:_JAVA_OPTION值:-Xmx750m

仅供参考: 您可以在Intellij中找到默认的VMoption help->编辑自定义VM选项,在此文件中,您可以看到堆的最小和最大大小。**

答案 12 :(得分:-1)

首先,当你有4 GB的RAM时使用页面文件是没用的。 Windows无法访问超过4GB(实际上,由于内存漏洞较少),因此不使用页面文件。

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

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