Java Performance - 如何调查解决内存问题

JVM 的内存溢出/不足/OutOfMemoryError/垃圾收集恶性循环是需要解决,又是屡见不鲜的问题。

建议阅读官方的 Troubleshooting Guide for Java SE 6 with HotSpot VM > Troubleshooting Memory Leaks

  • 首先清楚判定问题 - GC 日志是判断内存问题最准确的方法,因为 Java 的内存问题的本质是 GC 问题
    • Heap 堆不足溢出
    • Stack 堆栈不足溢出
    • Perm 堆不足溢出 - Java 8 取消了 Perm
    • 垃圾收集的恶性循环 - 注意:这几乎是最最常见的现象
  • Stack 堆栈不足溢出 - 错误是 StackOverFlowError

JVM 会打印出来具体的 Stack Trace

如果 Stack 比较大但是没有递归,那么调大 -Xss ( Server 默认 1024K )

如果 Stack Trace 显示递归,那么修改代码

 

  • Perm 堆不足溢出 - OutOfMemoryError 带着 PermGen space

调大 -XX:MaxPermSize,比如 768m

  • Heap 堆不足溢出 - OutOfMemoryError 带着 Heap Space

解决:调大 -Xmx,如果够大了需要 DEBUG - 参照下面 DEBUG HEAP

 

  • 垃圾收集的恶性循环 - 注意:这几乎是最最常见的现象

现象:

JVM 不相应,内存基本耗光,分析 GC 日志,会看到 花了很久做 FullGC ,释放了一点内存,很快又需要FullGC,比如 10 秒做了FullGC,1 秒后又需要FullGC 然后 10 秒完成 FullGC, 反复如此。

解决:调大 -Xmx,或者 DEBUG - 参照下面 DEBUG HEAP

  • DEBUG HEAP - 建议抓到 heapdump, 然后分析
    • 抓取 heapdump - 很多方法,但是常用如下 (注意针对非 IBM Java)

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path

--配置参数内存溢出时候自动抓取,注意往往内存问题表现为垃圾收集恶性循环,那就产生不出来。

 

jmap.exe -dump:format=b,file=HeapDump.hprof <pid>

--命令抓取

    • 分析 heapdump

建议 Eclipse Memory Analyzer (http://www.eclipse.org/mat/)

 

posted @ 2016-01-09 22:45  tang88seng  阅读(627)  评论(0编辑  收藏  举报