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

在这种情况下,我应该如何处理这个约束呢?

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

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

如果你能告诉我上述想法的细节或一些替代方案,如自动虚拟内存,动态扩展堆大小,那将是伟大的。


当前回答

如果你需要在运行时监控你的内存使用情况,java.lang.management包提供了mbean,可以用来监控你的虚拟机中的内存池(例如伊甸园空间,终身生成等),以及垃圾收集行为。

根据GC行为的不同,这些mbean报告的空闲堆空间会有很大的变化,特别是如果您的应用程序生成了许多后来被GC-ed的对象。一种可能的方法是监视每次全gc之后的空闲堆空间,您可以使用它来决定是否通过持久化对象来释放内存。

最终,最好的办法是在性能可以接受的情况下尽可能限制内存保留。正如前面的评论所指出的,内存总是有限的,但你的应用程序应该有一个策略来处理内存耗尽。

其他回答

在android studio中添加/更改gradle末尾的这一行。属性(全局属性):

...
org.gradle.jvmargs=-XX\:MaxHeapSize\=1024m -Xmx1024m 

如果它不起作用,您可以重试大于1024的堆大小。

如果你继续分配和保持对对象的引用,你将填满你所拥有的任何数量的内存。

一个选择是做一个透明的文件关闭和打开时,他们切换选项卡(你只保留一个指向文件的指针,当用户切换选项卡,你关闭和清除所有的对象…它会使文件更改变慢…但是…),并且可能只在内存中保留3或4个文件。

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

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

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

请记住,如果你把一个东西放入一个集合,然后忘记它,你仍然有一个强引用,所以取消集合,清理它或对它做些什么…如果没有,您将发现内存泄漏很难找到。

也许,使用弱引用的集合(weakhashmap…)可以帮助解决内存问题,但你必须小心使用它,因为你可能会发现你要找的对象已经被收集了。

我发现的另一个想法是开发一个持久的集合,存储在数据库对象最少使用和透明加载。这可能是最好的方法……

如果这个错误在APK生成过程中出现在react-native中,cd到你的项目中的android文件夹,并执行:

./gradlew clean

then

./gradlew assembleRelease

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

在java中解决OutOfMemoryError的简单方法是通过使用JVM选项-Xmx512M来增加最大堆大小,这将立即解决您的OutOfMemoryError。这是我在Eclipse, Maven或ANT中得到OutOfMemoryError时的首选解决方案,因为基于项目的大小,您可以很容易地耗尽内存。

这是一个增加JVM最大堆大小的例子,如果你在java应用程序中设置堆大小,最好保持-Xmx与-Xms的1:1或1:1.5的比例。

导出 JVM_ARGS=“-Xms1024m -Xmx1024m”

参考链接

如果在执行junit测试后立即发生此错误,则应执行Build ->重建项目。