首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java在填满堆空间之前崩溃

Java在填满堆空间之前崩溃
EN

Stack Overflow用户
提问于 2012-02-15 10:00:23
回答 3查看 3.3K关注 0票数 2

我有一个需要处理大量数据的java模拟器。它工作得很好,但我得到了一个int[100000][100][2]数组和其他大的数组。程序会说内存不足。(Java.lang.outOfMemoryError)

一切都很好,我只是给它更多的内存,但它似乎总是运行约300M,即使我允许它2 2GB。这一切都来自于观看任务管理器。

是我的系统出了什么问题,还是这只是一个我需要处理的java问题?

@DanielPryden

操作系统: Win 7板载32位4 4GB内存

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

错误数据: Had必须从集成开发环境中获取(使用IntelliJ)。我不知道从cmd怎么做。我想这就是你要找的东西。

代码语言:javascript
复制
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)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-02-15 14:46:57

如果您在32位Windows操作系统上运行,则不可能分配完整的2 2GB空间。即使您在Windows内部胡乱操作,您得到的最大可用地址空间也是3 3GB,而且即使这样,它也不会全部是连续的(而且JVM需要连续的空间来构建Java堆)。在实践中,使用Sun/Oracle JVM时,我从来没有成功地分配过大于1.5 by的堆--如果您使用的是JNI,那么您所链接的任何all都会减少最大可能的堆。

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

最后,如果您能找到一种方法将处理拆分到单独的进程中--即运行多个Java实例,每个实例都有自己要操作的数据集,并使用套接字或文件在它们之间通信,那么您可能会获得更好的结果。也就是说,使用32位Windows操作系统时,您可能仍然无法使用4 4GB的RAM,更不用说更大的内存了。

票数 4
EN

Stack Overflow用户

发布于 2012-02-15 10:08:43

您可能会遇到堆碎片问题。即使设置了-Xmx2GB,上面的整数数组也需要一个块连续内存。我也建议固定最小堆大小,例如,-Xms2GB。当然,由于操作系统开销、其他进程等原因,这要求您的计算机实际具有远高于2 2GB的内存。

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

票数 5
EN

Stack Overflow用户

发布于 2012-02-15 10:20:25

堆内存分为三个空间:

旧空间Generation

  • Survivor
  • 伊甸园空间

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

在我的jvm(1.6.26)中,默认的比率是30/70,因此老一代的对象的最大大小被限制在700Mb (使用-Xmx1G)。

但是,您可以使用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,8 8Gb内存)。考虑到单个数组在内存中大约占用200Mb+,我同意brettw的观点,即没有这种大小的连续内存块会导致这个问题(而不是生成大小)。固定使用集合搭配普通数组或购买更多内存(推荐:-)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9286934

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档