【问题标题】:OutOfMemoryError in Java on one plattform, but not the another one一个平台上的 Java 中的 OutOfMemoryError,但不是另一个平台
【发布时间】:2012-08-03 06:14:48
【问题描述】:

我遇到了一个关于 outOfMemory 错误的奇怪问题。 我写了一个应用程序,它在某些部分内存使用量很大。 在我的笔记本电脑(linux,64 位,eclipse indigo,vmargs:xms:40,xmx:512,4gb 物理内存)上,应用程序运行没有任何问题。 在另一台电脑(WinXP SP3、32 位、eclipse juno、vmargs:xms:40、xmx:1024(!)、2gb 物理内存)上,应用程序以标题中所述的错误终止。 两台机器都使用 oracle 的 java 7 jdk。 这怎么可能,应用程序在另一台比我的笔记本电脑拥有更多堆空间的电脑上失败。 我在笔记本电脑上开发了应用程序...但我认为这不应该是导致此错误的原因,对吧?

【问题讨论】:

  • 您的虚拟内存可能已用完。 64 位操作系统可以为进程提供比 32 位操作系统更多的虚拟内存。
  • 你能粘贴堆栈跟踪吗?我怀疑你可能会用完 PermGen 空间或类似的东西。
  • 问题已经回答了,斯蒂芬和彼得的回答非常有帮助。当前解决此问题的方法是在运行配置中定义 vm args。

标签: java memory out-of-memory cross-platform jvm-arguments


【解决方案1】:

Hotspot Java 的 32 位和 64 位版本对于如何确定堆的默认最大大小有不同的策略。在 32 位 JVM 上,使用固定的默认堆大小。在 64 位 JVM 上,堆大小取决于系统上的物理内存量。

解决方案是使用java 命令的-Xmx 选项显式设置最大堆大小。


在您的情况下,您已经在使用 -Xmx 参数,并且(显然)您在 32 位平台上使用了更大的值……而 32 位版本将首先消亡!我能想到一些可能的解释(可能性越来越小):

  • 您的 32 位机器没有足够的交换空间,无法满足 JVM 在尝试增加堆时对更多内存的请求。

  • 您的应用程序正在计算有多少可用内存并相应地调整其行为...但在大内存情况下会出错。

  • 两种情况下应用程序的输入存在一些差异,这就是问题所在。

  • 应用程序正在使用内存映射文件(或其他类似文件),这些文件占用了很大一部分地址空间......减少了堆可用的地址空间。在 64 位机器上,您有许多 GB 的地址空间,但在 32 位 Windows XP 机器上,您的应用程序的地址空间将被操作系统和指令集/硬件架构限制在 ~2Gb。

(您对问题的更改描述无济于事......)


如果您从 Eclipse 启动应用程序,您可能会将 Eclipse JVM 使用的 -Xmx 设置与运行应用程序的 JVM 使用的 -Xmx 设置混淆。如果您没有在应用程序的启动器配置中明确设置 -Xmx 选项...它将使用默认堆大小!


回应您的评论:

但我必须实现一个应用程序,该应用程序将作为 jar 包含在另一个项目中,这是一个 eclipse 插件..

对于 Eclipse 插件,JVM 大小由父 Eclipse 确定。你的插件在这件事上没有发言权。如果您的插件需要大量堆空间,则需要让用户手动调整 Eclipse 堆参数。

如果您从另一个 Eclipse 实例启动该 Eclipse 实例...我不确定应用程序启动器参数是否会产生任何影响。但这应该只对开发插件的您(和其他人)有意义。

(对于可执行 JAR 文件,无法在 JAR 清单中指定堆大小。但还有其他选项 - 请参阅 Can I set Java max heap size for running from a jar file?。)

【讨论】:

  • 他使用“xmx”并说明他在两种情况下都使用了哪些值。
  • 非常感谢,这工作正常.. 但我必须实现一个应用程序,该应用程序将作为一个 jar 包含在另一个项目中,这是一个 Eclipse 插件.. 我不知道如何确保正如您提到的,明确使用 java -xmx 选项。在我的项目的运行配置中设置 vm 参数就足够了吗?还是会被父 eclipse 插件覆盖,如果他们没有设置任何 vm args ?
  • @PeterLawrey - 他这么说,但他可能错了。请参阅我的最后一段。
  • +1 你可能是对的,他需要检查它是否已按照他的想法设置,因为 32 位客户端 JVM 的默认最大值相当低。
  • 感谢大家,对于改进的答案,我现在明白了,失败的原因是什么。
【解决方案2】:

并非所有 OutOfMemoryErrors 都是相同的。您可以从

获得 OutOfMemoryError
  • 堆空间不足
  • GC 太多。
  • 缺乏烫发
  • 堆栈空间不足(创建新线程)
  • 交换空间不足
  • 其他我忘记了。

您需要查看实际错误,我怀疑您的虚拟内存不足,因为您在 Windows XP 上总共只有大约 1.5 GB。

您可能会发现减少最大堆大小可以解决此问题,因为它会增加可用虚拟内存。


您需要检查您是否真的设置了您认为的最大值。在 64 位服务器 JVM 上,默认值可能很好(在这种情况下,您永远不需要设置它们)在 32 位客户端 JVM 上,默认值是相当的。

【讨论】:

  • 尝试在 eclipse 运行配置中通过 vm args 减小最大堆大小...将其设置为 512mb .. 应用程序失败..将其设置为 1024mb 应用程序成功...但在我的 linux 机器上我正在使用最大堆大小为 512mb,在 eclipse.ini 中设置,这工作正常..这怎么可能?
  • 我很困惑,在最初的问题中,您说 512 MB 的工作有效,而 1024 的失败。你说的是哪台机器?
  • 好的,澄清一下.. winXP 机器:512 mb --> 失败,1024 mb --> 成功... 在 linux 上:512mb -> 成功,但在 linux 上 jvm args 设置在eclipse.ini 而不是在运行配置中,就像在 windows 机器上一样..
  • eclipse.ini 为 Eclipse 设置参数,仅此而已。你能以同样的方式为两个系统设置运行时配置吗?
  • 你是对的,在 linux 上运行配置中没有提供 xmx args,这就是它起作用的原因:) 非常感谢你的回答 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-15
  • 2014-04-28
  • 1970-01-01
  • 2011-07-02
  • 1970-01-01
相关资源
最近更新 更多