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

565

我正在使用Java 5编写客户端的Swing应用程序(图形字体设计器)。最近,由于我在内存使用上没有保守,因此遇到了java.lang.OutOfMemoryError: Java heap space 错误。用户可以打开无限数量的文件,而程序会将已打开的对象保存在内存中。经过快速研究,我发现在Windows机器上JVM默认的最大堆大小为64MB,详情请参阅Java虚拟机5.0中的人体工程学等文献。

鉴于这种情况,我应该如何处理这个限制呢?

我可以使用命令行选项最大堆大小增加到可用RAM,然后编写一些启动程序或脚本。但是,增加到一些有限的最大值并不能彻底解决问题。

我可以重写我的一些代码,经常将对象持久化到文件系统中(使用数据库也是同样的道理),以释放内存。这可能有效,但也需要付出很多努力。

如果您能指导我关于上述想法的详细信息或类似自动虚拟内存,动态扩展堆大小的替代方案,那就太好了。


默认的最大堆大小为64 MB,这是在J2SE 5.0之前的设置。有关J2SE 8.0信息,请参阅"http://docs.oracle.com/javase/8/docs/technotes/guides/vm/gc-ergonomics.html"上的“垃圾收集器人体工程学”。 - Andy Thomas
5
如果您因为每个OOM问题都被重复到这个问题而来到这里,请确保您也查看以下内容:https://dev59.com/SnVC5IYBdhLWcg3wbQfA 它提供了一种在OOM之前“及时”清理内存引用的解决方案。SoftReferences可能是解决您实际问题的工具。 - Steve Steiner
Sun/Oracle JVM 一直非常严格地规定要使用多少内存(如果不规定,则会使用一些有趣的默认值)。那是微软 JVM 的其中一个好处 - 它非常快速,并且可以使用机器拥有的任何内存。 - Thorbjørn Ravn Andersen
在我的情况下,我错过了将 gradle.properties 文件添加到我的项目中。 - Mohd Qasim
31个回答

4
如果您正在使用Android Studio,只需将以下行添加到 gradle.properties 文件中:

org.gradle.jvmargs = -Xmx2048m -XX:MaxPermSize = 512m -XX:+ HeapDumpOnOutOfMemoryError -Dfile.encoding = UTF-8


3

关于Netbeans,您可以设置最大堆大小来解决问题。

进入“运行”,然后 --> “设置项目配置” --> “自定义” --> 弹出窗口的“运行” --> “VM选项” --> 填写“-Xms2048m -Xmx2048m”。


3

Android Studio

文件 -> 清除缓存并重新启动 对我有用 :)


1
如果在Wildfly 8和JDK1.8中出现此问题,则需要指定MaxMetaSpace设置而不是PermGen设置。
例如,我们需要在wildfly的setenv.sh文件中添加以下配置。 JAVA_OPTS="$JAVA_OPTS -XX:MaxMetaspaceSize=256M" 有关更多信息,请查看Wildfly Heap Issue

1

如果您不断分配并保留对象的引用,您将填满任何数量的内存。

一种选择是在切换选项卡时进行透明文件关闭和打开(您仅保留文件指针,当用户切换选项卡时,您关闭并清除所有对象...这会使文件更改变慢...但是),可能只保留3或4个文件在内存中。

另一件事情是,当用户打开文件时,加载它,并拦截任何OutOfMemoryError,然后(因为无法打开文件)关闭该文件,清除其对象并警告用户应关闭未使用的文件。

您动态扩展虚拟内存的想法并不能解决问题,因为机器的资源有限,所以您应该小心处理内存问题(或者至少要小心处理它们)。

我看到的一些内存泄漏提示是:

-->请记住,如果将某些内容放入集合中,然后忘记它,您仍然对其有强引用,因此将集合置为空值,清理它或对其进行某些操作...否则,您将发现难以找到内存泄漏。

--> 或许,使用带有弱引用的集合(WeakHashMap等)可以解决内存问题,但是你必须小心使用,因为你可能会发现你要查找的对象已经被回收了。

--> 另一个想法是开发一个持久化集合,将最少使用的对象存储在数据库中,并进行透明加载。这可能是最好的方法...


1
Java OOM堆空间问题也可能在您的DB连接池已满时出现。
我遇到了这个问题,因为我的Hikari连接池(升级到Spring boot 2.4.*后)已经满了,无法再提供连接(所有活动连接仍在等待从数据库获取结果)。
问题是我们JPA Repositories中的一些本地查询包含"ORDER BY ?#{#pageable}",在升级后获取结果需要很长时间。
从所有JPA存储库的本地查询中删除"ORDER BY ?#{#pageable}",OOM堆空间问题以及连接池问题得到解决。

1
如果在React Native的APK生成过程中出现此错误,请进入项目中的android文件夹并执行以下操作:
./gradlew clean

那么

./gradlew assembleRelease

如果错误仍然存在,那么请重新启动您的计算机。

1
如果该错误发生在您的JUnit测试执行后,请执行 Build -> Rebuild Project

0

如果一切尝试都失败了,除了增加最大堆大小之外,还可以尝试增加交换空间大小。对于Linux系统,目前可以在https://linuxize.com/post/create-a-linux-swap-file/中找到相关的指令。

如果您在嵌入式平台上编译大型程序,这可能会有所帮助。


0
在Intellij中,只需执行“构建项目”即可。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接