我收到了OutOfMemoryError: Java heap space
我是否可以使用任何工具找到根本原因?
答案 0 :(得分:2)
添加这些JVM参数,这会将垃圾收集详细信息记录到日志文件中。
-Xloggc:gc_memory_logs.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
日志看起来像这样,
1.703: [GC [PSYoungGen: 132096K->16897K(153600K)] 132096K->16905K(503296K), 0.0171210 secs] [Times: user=0.05 sys=0.01, real=0.01 secs]
3.162: [GC [PSYoungGen: 148993K->21488K(153600K)] 149001K->22069K(503296K), 0.0203860 secs] [Times: user=0.04 sys=0.00, real=0.02 secs]
4.545: [GC [PSYoungGen: 153584K->21484K(153600K)] 154165K->25309K(503296K), 0.0224490 secs] [Times: user=0.06 sys=0.01, real=0.02 secs]
6.159: [GC [PSYoungGen: 153580K->21472K(285696K)] 157405K->33127K(635392K), 0.0271700 secs] [Times: user=0.08 sys=0.01, real=0.03 secs]
获得此日志后,您可以使用许多不同的工具(http://www.fasterj.com/tools/gcloganalysers.shtml)分析日志。 一个这样的工具是垃圾。 https://code.google.com/a/eclipselabs.org/p/garbagecat/
使用此工具,您可以分析日志,这会产生如下结果
========================================
SUMMARY:
========================================
# GC Events: 18
GC Event Types: PARALLEL_SCAVENGE
Max Heap Space: 967680K
Max Heap Occupancy: 700911K
Max Perm Space: 0K
Max Perm Occupancy: 0K
Throughput: 100%
Max Pause: 82 ms
Total Pause: 582 ms
First Timestamp: 1703 ms
Last Timestamp: 56428185 ms
========================================
ANALYSIS:
========================================
========================================
0 UNIDENTIFIED LOG LINE(S):
========================================
一旦知道了结果,就可以相应地调整堆和永久内存设置。
例如,
-Xms512m -Xmx2g -XX:PermSize=512m -XX:MaxPermSize=2g
除此之外,我们可以使用JDK附带的其他有用工具,如
jvisualvm
jconsole
答案 1 :(得分:2)
您可以使用eclipse mat之类的分析工具分析应用程序的堆转储,以了解消耗了多少堆。
但首先您需要获取应用程序的堆转储。
要在发生OOM错误时让JVM 自动为您生成堆转储,您可以使用-XX:+HeapDumpOnOutOfMemoryError
选项。最重要的是,您还可以使用-XX:HeapDumpPath
选项告诉JVM生成文件的位置。
java -XX:HeapDumpPath="D:\heapdumps\YourApp.hprof" -XX:+HeapDumpOnOutOfMemoryError -jar YourApp.jar
生成该文件后,您可以在mat中打开它并进行分析。
您还可以在应用程序运行时随时手动生成堆转储。为此,您可以使用jdk附带的jmap
命令。
jmap -dump:live,format=b,file="D:\heapdumps\YourApp.hprof" process_id_of_your_app
您可以使用jdk附带的工具jps
轻松找到应用程序的进程ID。
jps -m
答案 2 :(得分:1)
是的,它们被称为profilers。市场上有很多选择。只需从Profiler中的JVM加载内存转储,它就会显示内存使用情况,并可以帮助您找出问题所在。
JDK附带VisualVM,自Java SE 7 u 40起,您拥有Java Mission Control(免费许可证)。
作为个人建议,请使用Eclipse Memory Analyzer a.k.a。MAT(免费许可证)或Yourkit(商业许可证)进行内存转储分析。
免责声明:我不同意任何这些公司。只需提供这些工具的快乐用户的信息。