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

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

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

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

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


当前回答

我也遇到了同样的问题,从java堆大小。

如果您使用java 5(1.5),我有两个解决方案。

只需安装jdk1.6,然后转到eclipse的首选项,并设置jav1 1.6的jre路径。 检查你的VM参数,不管它是什么。 只需在VM参数中所有参数的下面添加一行 -Xms512m -Xmx512m -XX:MaxPermSize=…m(192m)。

我认为它会起作用……

其他回答

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

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

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

我也遇到了同样的问题,从java堆大小。

如果您使用java 5(1.5),我有两个解决方案。

只需安装jdk1.6,然后转到eclipse的首选项,并设置jav1 1.6的jre路径。 检查你的VM参数,不管它是什么。 只需在VM参数中所有参数的下面添加一行 -Xms512m -Xmx512m -XX:MaxPermSize=…m(192m)。

我认为它会起作用……

VM参数在eclipse中为我工作。如果您使用的是eclipse 3.4版本,请执行以下操作

运行——>运行配置——>然后选择maven build下的项目——>然后选择选项卡“JRE”——>然后输入-Xmx1024m。

或者你可以运行——>运行配置——>选择“JRE”选项卡——>然后输入-Xmx1024m

这将增加所有构建/项目的内存堆。以上内存大小为1gb。你可以按照你想要的方式进行优化。

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

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

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

我想添加建议从甲骨文故障排除文章。

线程thread_name异常:Java .lang. outofmemoryerror: Java堆空间

详细消息Java堆空间表示无法在Java堆中分配对象。此错误并不一定意味着内存泄漏

可能的原因:

简单的配置问题,指定的堆大小不足以满足应用程序的要求。 应用程序无意中持有对对象的引用,这可以防止对象被垃圾收集。 过度使用终结符。

此错误的另一个潜在来源来自于过度使用终结器的应用程序。如果类具有finalize方法,则该类型的对象在垃圾收集时不会回收其空间

在垃圾收集之后,对象将排队等待终结,这将在稍后发生。终结器由服务终结队列的守护线程执行。如果终结器线程无法跟上终结队列,那么Java堆就会被填满,并抛出这种类型的OutOfMemoryError异常。

可能导致这种情况的一种场景是,应用程序创建了高优先级线程,导致终结队列的增长速度快于终结线程服务该队列的速度。