Windows XP 上的 Java 最大内存
Posted
技术标签:
【中文标题】Windows XP 上的 Java 最大内存【英文标题】:Java maximum memory on Windows XP 【发布时间】:2010-09-15 07:59:13 【问题描述】:我一直能够为在 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。
【问题讨论】:
您会注意到在 32 位 shell 或 64 位 shell 中运行应用程序的最大差异,至少根据我的经验,尽管 64 位 WindowsXP 系统很少见。跨度> wiki.eclipse.org/Eclipse.ini - oracle.com/technetwork/java/javase/… 【参考方案1】:**有很多方法可以改变堆大小,例如,
-
文件->设置->构建、执行、部署->编译器在这里你会发现堆大小
file->setting->build、exceution、deployment->compiler->andriod 在这里你也可以找到堆大小。如果您遇到同样的问题,您可以将其用于 android 项目。
对我有用的是
设置适当的 JAVA_HOME 路径,以防你的 java 更新了。
创建新系统变量计算机->属性->高级设置->创建新系统变量
名称:_JAVA_OPTION 值:-Xmx750m
仅供参考: 你可以在 Intellij 中找到默认的 VMoption help->edit custom VM option,在这个文件中你可以看到堆的最小和最大大小。**
【讨论】:
【参考方案2】:Windows 的 Java 堆大小限制为:
在 32 位 Java 上最大可能的堆大小:1.8 GB 推荐 32 位 Java 的堆大小限制:1.5 GB(或 1.8 GB,带 /3GB 选项)这并不能帮助您获得更大的 Java 堆,但现在您知道不能超出这些值。
【讨论】:
【参考方案3】:似乎每个人都在回答关于连续记忆的问题,但却忽略了承认一个更紧迫的问题。
即使有 100% 的连续内存分配,您也不能在 32 位 Windows 操作系统上拥有 2 GiB 的堆大小(*默认情况下)。这是因为 32 位 Windows 进程无法处理超过 2 GiB 的空间。
Java 进程将包含 perm gen(Java 8 之前)、每个线程的堆栈大小、JVM/库开销(几乎随着每次构建而增加)除了堆。。 p>
此外,JVM 标志及其默认值在版本之间会发生变化。只需运行以下命令,您就会有所了解:
java -XX:+PrintFlagsFinal
许多选项会影响堆内和堆外的内存划分。留给您或多或少的 2 GiB 可玩......
重用我的部分this 答案(关于Tomcat,但适用于任何Java 进程):
Windows 操作系统 将 32 位进程的内存分配总共限制为 2 GiB(通过 默认)。
[你将只能]分配大约 1.5 GiB 的堆 空间,因为还有其他内存分配给进程 (JVM / 库开销、perm gen 空间等)。
Why does 32-bit Windows impose a 2 GB process address space limit, but 64-bit Windows impose a 4GB limit?
其他现代操作系统 [cough 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
【讨论】:
这个答案只说明了为什么他可能只能分配 2 GB,而不是为什么他可以在一台计算机上分配 1.4 GB 而在另一台计算机上只能分配 1.2 GB。他没有达到此处所述的 1.5 GB、2 GB 或 4 GB 限制。 JVM 标志的段落在某种程度上解释了为什么内存可能会因版本而异。另外,请注意我关于堆设置如何始终是总进程大小的(大)部分的观点 - 因此低于该设置可能仍会达到 2 GiB process 限制 - 另一个可能受到连续的限制内存分配。 或者可能是 1.5 GB 的限制,他正在分配 1.4 GB。现在更有意义 - 感谢您的澄清。【参考方案4】:这是增加分页大小的方法
-
右键我的电脑--->属性--->高级
在性能部分点击设置
单击高级选项卡
在虚拟内存部分,单击更改。它将显示您当前的分页
尺寸。
选择有可用硬盘空间的驱动器。
提供初始大小和最大大小...例如初始大小 0 MB 和最大大小
4000 MB。 (根据您的需要)
【讨论】:
【参考方案5】:我从(有限内存)virtuozzo VPS 运行 java 程序时收到此错误消息。我没有指定任何内存参数,并且发现我必须明确设置一个 small 数量,因为默认值一定太高了。例如。 -Xmx32m(显然需要根据您运行的程序进行调整)。
只是把它放在这里以防其他人收到上述错误消息而没有像提问者那样指定大量内存。
【讨论】:
【参考方案6】:Oracle JRockit 可以处理非连续堆,在带有 /3GB 开关的 Windows 2003/XP 上可以具有 2.85 GB 的 Java 堆大小。似乎碎片会对 Java 堆的大小产生相当大的影响。
【讨论】:
【参考方案7】:首先,当您有 4 GB 的 RAM 时使用页面文件是没有用的。 Windows 不能访问超过 4GB(实际上是因为内存漏洞而减少了),所以页面文件没有被使用。
其次,地址空间一分为二,一半给内核,一半给用户态。如果您的应用程序需要更多 RAM,请使用 boot.ini 中的 /3GB 选项(确保 java.exe 被标记为“大地址感知”(谷歌了解更多信息)。
第三,我认为你不能分配完整的 2 GB 地址空间,因为 java 在内部浪费了一些内存(用于线程、JIT 编译器、VM 初始化等)。使用 /3GB 开关可以获得更多信息。
【讨论】:
页面文件在 4GB 或 RAM 中无用的想法是错误的。如果没有页面文件,操作系统就无法从物理 RAM 中逐出未使用的进程数据(未使用服务的堆栈空间等),从而降低了可用于实际工作的 RAM 量。拥有页面文件可以释放 RAM。【参考方案8】:这与连续内存有关。
Here's some info I found online 之前有人问过这个问题,据说是来自“虚拟机之神”:
我们需要连续内存的原因 堆的区域是我们有一个 一堆边数据结构 由(缩放的)偏移量索引 堆的开始。例如,我们 跟踪对象引用更新 一个字节的“卡片标记数组” 对于每 512 字节的堆。什么时候我们 在我们拥有的堆中存储一个引用 标记相应的字节 卡片标记数组。我们右移 商店的目的地地址和 用它来索引卡片标记数组。 有趣的寻址算术游戏 不能在 Java 中做到(有 to :-) 玩 C++。
通常我们没有问题 适度的连续区域(最多约 在 Windohs 上为 1.5GB,在 Solaris 上高达约 3.8GB。 YMMV。)。在 Windohs 上, 问题主要是有一些 在 JVM 启动时会分解 地址空间。使用 /3GB 开关 不会变基这些库,所以他们 对我们来说仍然是个问题。
我们知道如何制作分块堆,但是 使用会有一些开销 他们。我们有更多要求更快 存储管理比我们做的 32 位 JVM 中更大的堆。如果你 真的很想大堆,切换到 64 位 JVM。我们仍然需要连续 记忆,但更容易进入 一个 64 位的地址空间。
【讨论】:
这很有趣。我总是问自己为什么要 1500 MB,现在我明白了,谢谢! 很抱歉跟进一个古老的问题,但这是我迄今为止看到的最佳答案。但是,如果 JVM 无法获得 最大 堆大小,为什么它会在启动时失败?它不应该安静地满足最小以上的最佳尺寸吗?【参考方案9】:请记住,Windows 具有虚拟内存管理,而 JVM 只需要在其地址空间中连续的内存。因此,系统上运行的其他程序不一定会影响您的堆大小。会妨碍您的是加载到您的地址空间中的 DLL。不幸的是,Windows 中的优化可以最大限度地减少链接期间 DLL 的重定位,这使得您更有可能拥有碎片化的地址空间。除了通常的东西之外,可能会侵入您的地址空间的东西包括安全软件、CBT 软件、间谍软件和其他形式的恶意软件。差异的可能原因是不同的安全补丁、C 运行时版本等。设备驱动程序和其他内核位有自己的地址空间(4GB 32 位空间中的另外 2GB)。
您可以尝试在您的 JVM 进程中检查您的 DLL 绑定,并尝试将您的 DLL 重新设置为更紧凑的地址空间。不好玩,但如果你绝望了……
或者,您可以切换到 64 位 Windows 和 64 位 JVM。尽管其他人建议,虽然它会消耗更多 RAM,但您将拥有更多更多连续虚拟地址空间,并且连续分配 2GB 将是微不足道的。
【讨论】:
使用进程资源管理器查看内存 dll 的加载位置。通常,一些更新的驱动程序会将自己粘在地址空间的中间。使用 REBASE 命令,您可以轻松地将它们推开。但请记住,dll 可能会再次更新并破坏。 @Christopher,是否可以在 32 位 Windows XP 上使用 64 位 JVM? @Pacerier 抱歉,我错过了您的查询。 AFAIK,这是不可能的。 OS X 为 64 位用户空间和 32 位内核提供了一些技巧,但我还没有听说过适用于 Windows 的任何此类技巧。 @ChristopherSmith,顺便说一句,您提到“系统上运行的其他程序不一定会影响您的堆大小”。如果是这样,我们如何解释这个结果:***.com/questions/9303889/…? @brianegge 如何使用进程资源管理器查看加载的 dll?【参考方案10】:Sun 的 JVM 需要连续内存。因此,可用内存的最大数量取决于内存碎片。特别是驱动程序的 dll 在加载到某些预定义的基地址时往往会导致内存碎片化。因此,您的硬件及其驱动程序决定了您可以获得多少内存。
Sun 工程师声明的两个来源:forumblog
也许是另一个 JVM?你试过Harmony吗?我认为他们计划允许非连续内存。
【讨论】:
但是我能够在只有 1GB RAM(加上虚拟内存)的机器上分配 1300MB。我的 2GB RAM 机器(也带有虚拟内存)只能分配 1200MB。 和谐死了不是吗? 是的:“Apache Harmony 自 2011 年 11 月 16 日起在 Apache 软件基金会退休。”【参考方案11】:我认为这与此响应所暗示的 Windows 的配置方式有关: Java -Xmx Option
更多测试:我能够在一台只有 768MB 物理 RAM(加上虚拟内存)的旧 Windows XP 机器上分配 1300MB。在我的 2GB RAM 机器上,我只能获得 1220MB。在其他各种公司机器(使用较旧的 Windows XP)上,我能够获得 1400MB。具有 1220MB 限制的机器是相当新的(刚从戴尔购买),所以它可能有更新(并且更臃肿)的 Windows 和 DLL(它运行的是 Window XP Pro 版本 2002 SP2)。
【讨论】:
它也可能受到您的虚拟内存设置的影响。 我测试的所有机器的虚拟内存至少是物理 RAM 的两倍。 请注意,你真的不想在java中真正使用虚拟内存,因为GC性能会变得非常糟糕。内存量取决于哪些dll已经被加载并碎片化了内存。【参考方案12】:如果您分配一个巨大的块,sun 的 JDK/JRE 需要连续的内存量。
操作系统和初始应用程序倾向于在加载过程中分配零碎的可用 RAM。如果连续块不可用,则 SUN JDK 无法使用它。 Bea的JRockit(被Oracle收购)可以分片分配内存。
【讨论】:
【参考方案13】:JVM 需要连续内存,根据正在运行的其他内容、之前运行的内容以及 Windows 管理内存的方式,您最多可以获得 1.4GB 的连续内存。我认为 64 位 Windows 将允许更大的堆。
【讨论】:
我认为现代操作系统模拟连续内存。从 80486 开始,x86 架构支持分页,以便于重新排列物理内存。 Mnemeth:首先,WINAPI 中有一个特定的 API (AllocateUserPhysicalPages),用于数据库和虚拟机等高级工具,这些工具最好在不影响 Windows 的情况下自行管理内存。其次,分页是 80386 保护模式功能,而不是 80486。以上是关于Windows XP 上的 Java 最大内存的主要内容,如果未能解决你的问题,请参考以下文章