我有这个需要处理大量数据的java模拟器。它运行正常,但我可以使用int[100000][100][2]
以及其他大数组来运行。该程序说它的内存不足。 (Java.lang.outOfMemoryError
)
一切都很好,我只是给它更多的记忆,但它似乎总是耗尽〜300M左右,即使我允许它2GB。这一切都来自观看任务经理。
我的系统出了什么问题,或者这只是我需要处理的java事情?
@DanielPryden
操作系统:在机上赢取7个32Bit 4GB的ramJVM命令: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)
答案 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没有连续的这种大小的内存块导致这个问题(不是生成大小)。至于修复 - 使用集合与普通阵列或购买更多内存(推荐:-))