当前位置: 首页 > Java > 正文

Java OOM示例、原因查找和解决(一)

关键字:
1 星2 星3 星4 星5 星 (2 次投票, 评分: 5.00, 总分: 5)
Loading ... Loading ...
baidu_share

当Java程序运行时,会有很多种造成OOM的现象,这里面有些会比较容易查找出原因,而有些会非常困难,下面是来看一些OOM的Example。

以-Xms20m -Xmx20m -Xmn10m -XX:+UseParallelGC参数运行com.bluedavy.oom.JavaHeapSpaceCase1

运行后在输出的日志中可看到大量的Full GC信息,以及:

java.lang.OutOfMemoryError: GC overhead limit exceeded
和java.lang.OutOfMemoryError: Java heap space

根据上面所说的OOM种类,可以知道这是在new对象或数组时Java Heap Space不足造成的,对于这种OOM,需要知道的是程序中哪些部分占用了Java Heap。

要知道程序中哪些部分占用了Java Heap,首先必须拿到Java Heap中的信息,尤其是OOM时的内存信息,在Sun JDK中可通过在启动参数上加上-XX:+ HeapDumpOnOutOfMemoryError来获得OOM时的Java Heap中的信息,当出现OOM时,会自动生成一个java_pid[pid].hprof的文件。

于是在启动参数上加上上面的参数,再次运行JavaHeapSpaceCase1,可看到在当前运行的路径下生成了一个java_pid10852.hprof(由于pid不同,你看到的可能是不一样的文件名)的文件,在拿到这个文件后,就可通过mat(http://www.eclipse.org/mat/)来进行分析了。

用mat打开上面的文件(默认情况下mat认为heap dump文件应以.bin结尾,因此请改名或以open file方式打开),打开后点击dominator_tree,可看到sun.misc.Launcher$AppClassLoader占据了大部分的内存,继续点开看,则可看到是由于com.bluedavy.oom.Caches中有一个ArrayList,其中存放的对象占据了大部分的内存,因此解决这个OOM的办法是,让Caches类中放的对象总大小是有限制的,或者限制放入Caches的ArrayList中的对象个数。

这种情况造成的OOM,在实际的场景中当使用缓存时很容易产生,对于所有的缓存、集合大小都应给定限制的最大大小,以避免出现缓存或集合太大,导致消耗了过多的内存,从而导致OOM。

本文固定链接: http://www.chepoo.com/java-oom-demo-error-solution-1.html | IT技术精华网

Java OOM示例、原因查找和解决(一):等您坐沙发呢!

发表评论