我正在Java 5上编写客户端Swing应用程序(图形字体设计器)。 最近,我遇到了java.lang.OutOfMemoryError: Java heap space
错误,因为在内存使用方面我并不保守。 用户可以打开无限数量的文件,并且程序将打开的对象保留在内存中。 经过快速研究,我在5.0 Java虚拟机中发现了人机工程学,其他人则说在Windows计算机上,JVM的默认最大堆大小为64MB
。
在这种情况下,我应该如何处理这种限制?
我可以使用java的命令行选项来增加最大堆大小 ,但这需要找出可用的RAM并编写一些启动程序或脚本。 此外,增加到某个有限的最大值并不能最终解决这个问题。
我可以重写一些代码,以将对象频繁地持久保存到文件系统中(使用数据库是同一回事)以释放内存。 它可以工作,但是可能也很多。
如果您可以将上述想法的细节或自动虚拟内存,动态扩展堆大小等替代方案的细节介绍给我,那将会很棒。
#1楼
是的,使用-Xmx
可以为JVM配置更多的内存。 为确保您不会泄漏或浪费内存。 进行堆转储,然后使用Eclipse Memory Analyzer分析您的内存消耗。
#2楼
如果您需要在运行时监视内存使用情况,则java.lang.management
包提供了MBeans
,可用于监视VM中的内存池(例如,eden空间,保有期限的生成等)以及垃圾回收行为。
这些MBean报告的可用堆空间将根据GC行为而有很大的不同,尤其是如果您的应用程序生成了许多对象,这些对象随后将由GC处理。 一种可能的方法是监视每个完整GC之后的可用堆空间,您可以使用它来决定是否通过持久化对象来释放内存。
最终,最好的选择是在性能仍然可以接受的同时,尽可能地限制内存的保留。 如之前的评论所述,内存总是有限的,但是您的应用程序应具有应对内存耗尽的策略。
#3楼
请按照以下步骤操作:
从tomcat / bin中打开
catalina.sh
。将JAVA_OPTS更改为
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1536m -Xmx1536m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC"
重启你的tomcat
#4楼
增大堆大小不是“固定”,而是“石膏”,100%临时。 它将在其他地方再次崩溃。 为避免这些问题,请编写高性能代码。
- 尽可能使用局部变量。
- 确保选择正确的对象(例如:在String,StringBuffer和StringBuilder之间选择)
- 为您的程序使用良好的代码系统(例如:使用静态变量VS非静态变量)
- 其他可能在您的代码上起作用的东西。
- 尝试移动多线程
#5楼
我在其他地方可以尝试读取-catch java.lang.OutOfMemoryError并在catch块上,可以释放所有您可能会使用大量内存的资源,关闭连接等等,然后执行System.gc()
然后重试您要做什么。
尽管我不知道这是否行得通,但这是另一种方式,但是我目前正在测试它是否可以在我的应用程序中运行。
这个想法是通过调用System.gc()来进行垃圾收集,该方法已知会增加可用内存。 您可以在执行内存吞噬代码后继续检查此问题。
//Mimimum acceptable free memory you think your app needs
long minRunningMemory = (1024*1024);
Runtime runtime = Runtime.getRuntime();
if(runtime.freeMemory()<minRunningMemory)
System.gc();
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3164578