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

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

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

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

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


当前回答

遵循以下步骤:

从tomcat/bin打开catalina.sh。 将JAVA_OPTS更改为 JAVA_OPTS = " -Djava.awt。无头= true -Dfile。encoding=UTF-8 -server -Xms1536m -Xmx1536m -XX:NewSize=256 6m -XX:MaxNewSize=256 6m -XX:PermSize=256 6m - xx: MaxPermSize = 256 - xx: + DisableExplicitGC” 重新启动tomcat

其他回答

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

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

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

是的,使用-Xmx,您可以为JVM配置更多内存。 确保你不会泄露或浪费内存。获取堆转储并使用Eclipse Memory Analyzer分析内存消耗。

遵循以下步骤:

从tomcat/bin打开catalina.sh。 将JAVA_OPTS更改为 JAVA_OPTS = " -Djava.awt。无头= true -Dfile。encoding=UTF-8 -server -Xms1536m -Xmx1536m -XX:NewSize=256 6m -XX:MaxNewSize=256 6m -XX:PermSize=256 6m - xx: MaxPermSize = 256 - xx: + DisableExplicitGC” 重新启动tomcat

当数据库连接池满时,Java OOM堆空间问题也会出现。

我遇到这个问题是因为我的Hikari连接池(升级到Spring boot 2.4.*时)已满,无法再提供连接(所有活动连接仍在等待从数据库获取结果)。

问题是我们在JPA存储库中的一些本地查询包含ORDER BY ?#{#pageable},这需要很长时间才能获得升级时的结果。

从JPA存储库中的所有本机查询和OOM堆空间问题以及连接池问题中删除ORDER BY ?#{#pageable}。

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

详情请看这里。