我遇到了outOfMemory错误的奇怪问题。 我编写了一个应用程序,它在某些部分使用了大量内存。 在我的笔记本电脑上(linux,64bit,eclipse indigo,vmargs:xms:40,xmx:512,4gb物理ram)应用程序运行没有任何问题.. 在另一台电脑上(WinXP SP3,32bit,eclipse juno,vmargs:xms:40,xmx:1024(!),2gb物理内存),应用程序终止,并在标题中声明错误。 两台机器都使用oracle的java 7 jdk。 这怎么可能,应用程序在另一台具有更多堆空间的PC上失败,而不是我的笔记本电脑。 我在笔记本电脑上开发了应用程序...但我认为这不应该是导致此错误的原因,对吗?
答案 0 :(得分:5)
32位和64位版本的Hotspot Java有关于如何确定堆的默认最大大小的不同策略。在32位JVM上,使用固定的默认堆大小。在64位JVM上,堆大小取决于系统上的物理内存量。
解决方案是使用java
命令的-Xmx
选项显式设置最大堆大小。
在你的情况下,你已经在使用-Xmx参数了,并且(显然)你在32位平台上使用了更大的值......并且32位版本首先死了!我可以想到一些可能的解释(降低可能性):
您的32位计算机没有足够的交换空间,并且在尝试扩展堆时无法满足JVM对更多内存的请求。
您的应用程序正在计算可用内存量并相应地调整其行为......但在大内存情况下出错了。
在两种情况下,应用程序的输入存在一些差异,这导致了问题。
应用程序正在使用内存映射文件(或类似的东西),这些文件占用了大部分地址空间......减少了堆可用的地址空间。在64位计算机上,您有许多千兆字节的地址空间,但在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?。)
答案 1 :(得分:4)
并非所有OutOfMemoryErrors都相同。您可以从
获取OutOfMemoryError您需要查看实际错误,我怀疑您的虚拟内存不足,因为Windows XP上总共只有大约1.5 GB。
您可能会发现减少最大堆大小修复此问题,因为它会增加可用虚拟内存。
你需要检查你是否真的设定了你认为的最大值。在64位服务器JVM上,默认值可能没问题(在这种情况下,您永远不需要设置它们)在32位客户端JVM上,默认值是公平的。