我总是可以为在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可识别。
答案 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堆大小限制为:
这无助于您获得更大的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会分散内存。因此,您的硬件及其驱动程序决定了您可以获得多少内存。
也许是另一个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)
操作系统和初始应用程序倾向于在加载过程中分配位和碎片,从而分割可用的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等。)。
其他现代操作系统[咳嗽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)
以下是增加分页大小的方法
答案 11 :(得分:0)
**有多种更改堆大小的方法,例如
对我有用的是
设置适当的适当JAVA_HOME路径,以防Java更新。
创建新系统变量计算机->属性->高级设置->创建新系统变量
仅供参考: 您可以在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开关获取更多信息。