![java.lang.OutOfMemoryError:Java 堆空间](https://linux22.com/image/649787/java.lang.OutOfMemoryError%EF%BC%9AJava%20%E5%A0%86%E7%A9%BA%E9%97%B4.png)
在我们的应用程序中,我们同时拥有 Apache 服务器(仅用于前端)和 JBoss 4.1(用于业务端)。我们使用 Ubuntu 12 作为服务器操作系统。我们的应用程序几乎每 2-3 小时就会连续抛出“java.lang.OutOfMemoryError:Java 堆空间”(因此应用程序开始抛出内存堆一个小时左右,然后在接下来的 2-3 小时内再次开始正常工作,然后再次开始抛出内存不足异常)。我们的 Java 内存设置是
-Xms512米-Xmx1024米
我们的服务器物理上拥有 6 GB 的 RAM。请告诉我们是否需要增加 Java 堆大小。如果是,考虑到物理 6GB 的 RAM,理想的大小应该是多少。
问候,Prateek
答案1
调试您的应用程序。如果几个小时后出现 OOM,那么很有可能应用程序确实出了问题,而且您无法通过添加更多内存来修复它。您只会增加更多时间,直到应用程序死机。此外,JBoss 4.1 非常老旧,所以我假设它上面没有运行任何特别的东西。检查日志中的连接泄漏、堆转储和堆栈跟踪,以查找泄漏的线索及其来源,在非生产环境中运行不同的使用测试,并测量内存在每个请求下的行为。您甚至可以使用 jmap 和 jdump 在测试前后生成堆转储和堆栈跟踪,以比较测试对事物状态的影响,或者安排它们以一定的时间间隔运行,然后检查哪些对象未被 GC 正确清理。此外,使用以下选项打开 GC 日志记录和转储:
set JAVA_OPTS=%JAVA_OPTS% -XX:OnOutOfMemoryError="%JAVA_HOME%\bin\jmap -dump:format=b,file=%JBOSS_HOME%\bin\heap_%%p.bin" -XX:ErrorFile=%JBOSS_HOME%\bin\hs_err_pid%%p.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=%JBOSS_HOME%\bin -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -Xloggc:%JBOSS_HOME%\bin\gc-%DATE:~-8,-4%%DATE:~-14,-12%%DATE:~-11,-9%.log -XX:-TraceClassUnloading
这将在您的 JBOSS_HOME\bin 文件夹中保存常规堆转储(heap_PID.bin)、堆栈跟踪(hs_err_pidPID.log)和垃圾收集日志(gc_DATE.log)(您可以随意调整)。
绝大多数 OOM 都是由于应用程序错误造成的,因此在将硬件投入到应用程序之前,务必先查看应用程序。确保其他一切都正确无误后再进行硬件开发。即使项目经理和开发人员讨厌你。
塞巴斯蒂安
答案2
如果加倍堆大小不能解决问题,正如乔建议的那样,我建议添加
-XX:+HeapDumpOnOutOfMemoryError
获取事后堆转储的参数,稍后您应该使用 Eclipse MAT 内存分析器或 JDK 的 jvisualvm 等工具仔细分析是否存在内存泄漏。
答案3
尝试将其加倍。如果没有太多其他进程占用 6GB 的 RAM,那么为 JVM 提供 1-2GB 的 RAM 应该没问题。
-Xms1024m -Xmx2048m
您还可以使用以下命令运行您的应用程序:
java -Xmx2g yourapp
您还可以尝试分析应用程序以发现可能的内存泄漏或找出导致应用程序占用如此多内存的原因。
看:控制台