java.lang.OutOfMemoryError: Java heap space的解决办法

来源:互联网 发布:Java四舍五入 编辑:程序博客网 时间:2024/05/29 16:39

Java堆内存的OutOfMemory异常是实际应用中比较普遍的内存溢出情况。本文是我总结的解决这种问题的一些浅见,欢迎各位拍砖..


关于OutOfMemoryError的解决办法网上的讨论也有很多,表面原因是堆内存不够用.但是深层原因可以分为两类,


一是内存溢出,二是内存泄漏.。


第一种情况比较简单,解决方法是通过优化Java的堆参数-Xmx, -Xms来解决问题,这里有具体做法。

http://www.blogjava.net/liuwentao253/archive/2008/06/03/205466.html


第二种就稍微复杂一些了,如果还想通过以上的方法来解决问题,最终的结果往往是治标不治本。

解决这种问题一般的手段是通过内存映像分析工具来对heapdump进行分析。heapdump文件是内存的快照,说白了就是某一时间点内存的使用情况.分析内存的目的是确定是否有内存泄漏发生.

首先,要做的是设置参数,以期获得heapdump文件. 具体怎么设置就不说了,可以参考这里 http://44424742.iteye.com/blog/1063522

然后,你要做的就是重现题目所说的这种问题,出现OutOfMemoryError时,这时如果第一步设置正确,就可以得到相应的heapdump文件了,恭喜你,成功了一半了!

第三步也是相当重要的一步,用内存分析软件来打开得到的文件,这种软件也有很多,笔者用的是IBM的heap analyzer.不过用内存分析软件要求你的内存必须大到足够可以载入heapdump文件。

最后就是分析heapdump文件,这就要求你对数据结构和代码本身的了解有相当的功底。举个例子来说,之前分析了一个heapdump文件,发现超过60%的内存被一个Cache链表占用,然后回到代码发现在loadCache同时load到了一个hashmap和一个链表,而清空时只清空了hashmap,反复的clear->load->clear导致链表不断的膨胀,直到OOM异常发生.

当然这种分析heapdump的方法也可能会发现内存中的对象还存活着,没有内存泄漏,那就要深入代码,检查是否某些对象生命周期过长,长时间持有内存的情况,从根本上优化代码.