填充堆空间之前Java崩溃

时间:2012-02-15 02:00:23

标签: java out-of-memory

我有这个需要处理大量数据的java模拟器。它运行正常,但我可以使用int[100000][100][2]以及其他大数组来运行。该程序说它的内存不足。 (Java.lang.outOfMemoryError

一切都很好,我只是给它更多的记忆,但它似乎总是耗尽〜300M左右,即使我允许它2GB。这一切都来自观看任务经理。

我的系统出了什么问题,或者这只是我需要处理的java事情?

@DanielPryden

操作系统:在机上赢取7个32Bit 4GB的ram

JVM命令:java -Xmx2048M -Xms2048M模拟器

错误数据:必须从IDE(使用IntelliJ)获取。我不知道如何从cmd做到这一点。我认为这就是你要找的东西。

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at Simulator.main(Simulator.java:63)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

3 个答案:

答案 0 :(得分:5)

您可能遇到堆碎片问题。即使您设置-Xmx2GB,上面的整数数组也需要块连续内存。我建议也固定最小堆大小,例如-Xms2GB。这当然要求您的机器实际上远远超过2GB,因为操作系统开销,其他进程等。

或者,您可以重新访问数据结构,看看是否真的需要这样一个连续的块。以某种方式将其分解可能会减少对大量连续内存块的需求。

答案 1 :(得分:4)

如果您在32位Windows操作系统上运行,则无法分配完整的2GB。即使您使用Windows内部设备,您将获得的最大可用地址空间是3GB,即使这样,它也不会是连续的(并且JVM需要连续的空间来构建Java堆)。实际上,使用Sun / Oracle JVM,我从来没有能够成功地分配大于1.5GB的堆 - 如果你使用JNI,你链接的任何DLL都会减少最大可能的堆英寸

如果你真的需要一个大堆,我会建议你尽可能转移到64位操作系统。其次,正如其他答案所指出的那样,如果你可以分配非连续的内存,那么更有可能成功。使用LinkedList或其他结构,以单独的块分配数据。这里有一点折衷;你可能希望每个块都包含一个至少为64Kb的数组。

最后,如果您可以找到将处理拆分为单独进程的方法,也就是运行多个Java实例,每个实例都有自己的数据集进行操作,并使用套接字或文件,您可能会得到更好的结果在他们之间进行沟通。也就是说,使用32位Windows操作系统,你可能仍然无法使用4GB内存,更不用说任何更大的内存。

答案 2 :(得分:2)

堆内存分为三个空格:

  • 老一代
  • 幸存者空间
  • 伊甸园空间

默认情况下,虚拟机会在每个集合中增大或缩小堆,以尝试将可用空间的比例保持为特定范围内每个集合的活动对象。此目标范围通过参数-XX:MinHeapFreeRatio =和-XX:MaxHeapFreeRatio =设置为百分比,并且总大小在-Xms以下由-Xms以上限制。

我的jvm(1.6.26)中的默认比率是30/70,因此旧一代对象的最大尺寸受限(使用-Xmx1G)700Mb。

但是你可以使用jvm选项调整代数。例如,您可以使用参数-Xmx1G -XX:NewRatio = 10运行您的类,并且可以将更大的对象放在内存中。

看起来Java并不是为了在内存中保存大型单片对象(如数组)。应用程序中内存的典型用法是一堆相对较小的对象的图形,通常只有在所有空格中空间不足时才会出现OutOfMemoryError。

下面是一些有用的(和有趣的阅读)文章:

Ergonomics in the 5.0 Java[tm] Virtual Machine

Tuning Garbage Collection with the 5.0 Java[tm] Virtual Machine

编辑:我无法在我的盒子上重现它(Mac OS X,8Gb RAM)。考虑到单个阵列在内存中大约需要200Mb +,我同意brettw没有连续的这种大小的内存块导致这个问题(不是生成大小)。至于修复 - 使用集合与普通阵列或购买更多内存(推荐:-))