诊断Java.lang.OutOfMemoryError(OOM),
诊断Java.lang.OutOfMemoryError(OOM),
在跟踪性能问题时,堆内存是首先应该被监控的最重要的组件之一。一旦堆内存的实际使用量超过其所允许的堆空间,就会产生堆内存压力。而这将导致频繁的全面垃圾回收事件,垃圾回收将窃取CPU周期,轻则导致响应时间延迟,重则导致必须重新启动Java虚拟机才能解决的内存溢出错误。
内存溢出错误(OOM)
当我运行应用时,出现了如下异常:
- java.lang.OutOfMemoryError: GC overhead limit exceeded[7,9]
- java.lang.OutOfMemoryError: Java heap space
第一条信息意味着,出于某种原因,垃圾收集器每次执行都花费了大量时间但只回收了很少量的内存,当我删除了如下代码后:
System.gc();
第一条信息消失了,取而代之的,系统出现了第二条信息。很明显堆内存空间依然存在问题。下面是我调查问题的步骤:
- 添加下面的Java启动参数
- -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
- 系统会生成gc.log文件
- -XX:+HeapDumpOnOutOfMemoryError
- 系统会生成堆内存转储文件
- -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
- 分析日志文件:
- 使用常规的文本编辑器查看gc.log 文件。
- 使用 Eclipse Memory Analyzer 查看 堆内存转储文件 (例如, java_xxx.hprof)
请注意,本文所讨论的所有虚拟机参数都是基于Hotspot虚拟机的。
Java命令行参数说明:
- -XX:+PrintGCDetails
- 打印更多的关于垃圾收集的信息。
- -XX:+PrintGCTimeStamps
- 打印从HotSpot 虚拟机开始执行直至垃圾收集事件发生所花费的时间(以秒为单位)。
- -Xloggc:gc.log
- 在每次垃圾收集时打印堆内存以及垃圾收集的信息。
在JDeveloper中可以按照如下方式设定:
- 右键选择你的项目(例如ViewController),显示出菜单
- 选择Project Properties…
- 选择Run/Debug/Profile
- 选择你Run Configuration(例如, Default)
- 点击Edit按钮
- 在Java虚拟机参数栏位设定 -Xloggc:gc.log -XX:-PrintGCDetails
运行你的应用并重现内存溢出异常,系统将会生成日志文件gc.log,
我的是在如下目录:
- …/system11.1.1.5.37.60.13/DefaultDomain
因为我的Web应用是部署在集成的WLS中,并且通过DefaultDomain来执行。
所以,想要理解gc.log文件的格式,请参考关联阅读[5,15]。
不过,gc.log文件并不能真正的帮到我们,因为他只是简要的打印了堆内存问题,
但并没有指出问题出在哪。
接下来我要做的是添加如下参数,并重新执行服务。
-XX:+HeapDumpOnOutOfMemoryError
当服务发生堆内存错误时,会生成java_pid30835.hprof文件。
Eclise内存分析器(Eclipse Memory Analyzer)
堆内存转储文件由HPROF(堆内存和CPU分析工具)生成,堆内存转储文件是2进制格式的,因此必须使用Eclpse Memory Analyzer 来查看。
你可以通过Eclipse Update manager 来安装Eclipse MAT,选择”General Purpose Tools “并安装”Memory Analyser (Incubation)”以及”Memory Analyser (Charts)”。
安装之后,双击堆内存转储文件并且选择”Leak Suspects Report”
Eclipse MAT会显示如下图表:
以及问题的嫌疑人:
调整堆内存空间
如果你观察到垃圾收集日志文件中有内存溢出错误,那么可以尝试将Java堆内存空间调整为你能够分配给Java虚拟机的物理内存空间的80%,基于具体是老年代空间还是永久代空间发生内存溢出,你可以像这样调整内存空间。
- 针对老年代发生内存溢出
- increase -Xms and -Xmx
- 针对永久代发生内存溢出
- increase -XX:PermSize and -XX:MaxPermSize
参考文献:
- Eclipse Update Manager
- Eclipse Memory Analyzer
- Java Hotspot VM Options
- Integrated WebLogic Server (WLS)
- Diagnosing a Garbage Collection problem
- Frequently Asked Questions about Garbage Collection
- GC Overhead Limit Exceeded
- HPROF: A Heap/CPU Profiling Tool in J2SE 5.0
- Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning
- Java Performance by Charlie Hunt and Binu John
- Understanding Garbage Collection
- Java HotSpot VM Options
- GCViewer (a free open source tool)
- Understanding Garbage Collector Output of Hotspot VM
英文原文:xmlandmore,编译:Wld5-王晓杰
译文地址: http://www.wld5.com/1586.html
【如需转载,请在正文中标注并保留原文链接、译文链接和译者等信息,谢谢合作!】
用户点评