如何处理“java.lang.OutOfMemoryError: Java heap space”错误?

2022-08-31 04:22:26

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

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

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

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

如果你能给我指出上述想法的细节或一些替代方案,如自动虚拟内存,动态扩展堆大小,那就太好了。


答案 1

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

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

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

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

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


答案 2

使用命令行选项运行 Java,该选项设置堆的最大大小。-Xmx

有关详细信息,请参阅此处


推荐