java - 如何处理 "java.lang.OutOfMemoryError: Java heap space"错误?

标签 java jvm out-of-memory heap-memory

我正在 Java 5 上编写客户端 Swing 应用程序(图形字体设计器)。最近,我遇到了 java.lang.OutOfMemoryError: Java heap space 错误,因为我对内存使用不保守。用户可以打开无限数量的文件,程序将打开的对象保存在内存中。经过快速研究,我发现 Ergonomics in the 5.0 Java Virtual Machine和其他人在 Windows 机器上说 JVM 默认最大堆大小为 64MB.

鉴于这种情况,我应该如何处理这个约束?

我可以使用 java 的 命令行 选项来增加 最大堆大小,但这需要确定可用 RAM 并编写一些启动程序或脚本。此外,将最大值增加到某个 有限 并不能最终解决这个问题。

我可以重写我的一些代码以频繁地将对象持久保存到文件系统(使用数据库是同一件事)以释放内存。它可以工作,但也可能需要很多工作。

如果您能向我指出上述想法的详细信息或自动虚拟内存、动态扩展堆大小等替代方法,那就太好了。

最佳答案

最终,无论您在什么平台上运行,您总是可以使用有限的最大堆。在 Windows 32 位中,这大约是 2GB (不是特别是堆,而是每个进程的总内存量)。碰巧 Java 选择使默认值更小(大概是为了让程序员无法创建具有失控内存分配的程序,而不会遇到这个问题并且必须检查他们正在做什么)。

因此,鉴于您可以采取多种方法来确定所需的内存量或减少正在使用的内存量。垃圾收集语言(如 Java 或 C#)的一个常见错误是保留对您不再正在使用的对象的引用,或者在您可以重用它们时分配许多对象.只要对象有对它们的引用,它们就会继续使用堆空间,因为垃圾收集器不会删除它们。

在这种情况下,您可以使用 Java 内存分析器来确定程序中的哪些方法正在分配大量对象,然后确定是否有办法确保它们不再被引用,或者不在第一名。我过去使用的一个选项是“JMP”http://www.khelekore.org/jmp/ .

如果您确定分配这些对象是有原因的,并且您需要保留引用(取决于您正在执行的操作,这可能是这种情况),您只需要在启动时增加最大堆大小程序。但是,一旦您进行了内存分析并了解了您的对象是如何分配的,您应该对您需要多少内存有一个更好的了解。

一般来说,如果您不能保证您的程序将在某些有限的内存中运行(可能取决于输入大小),您总会遇到这个问题。只有在用尽所有这些之后,您才需要考虑将对象缓存到磁盘等。此时,您应该有一个很好的理由说“我需要 Xgb 内存”,而您无法通过改进来解决它您的算法或内存分配模式。通常,这通常只适用于在大型数据集(如数据库或某些科学分析程序)上运行的算法,然后缓存和内存映射 IO 等技术变得有用。

关于java - 如何处理 "java.lang.OutOfMemoryError: Java heap space"错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37335/

相关文章:

java - JVM - 在没有显式调用的情况下打印堆栈跟踪

iPhone 内存不足,奇怪地崩溃

java - Android:FileObserver 不会收到有关 FS 更改的通知

java - 修改 ArrayList 内数组中的单个元素

java - 如何捕获 Beanshell 的输出

garbage-collection - 如何在过多的 GC 中尽快 OOM?

java - JVM指令-sload

java - 更快的分组时间方法

android - OpenGL ES VBO 奇怪的内存影响

java - "GC overhead limit exceeded"是失败的次要原因吗?