yinxin
作者yinxin2015-04-17 17:59
项目经理, 某金融机构

java堆内存溢出OutOfmemoryError

字数 2132阅读 1485评论 0赞 0

什么是内存泄露

看到网上有很多人都在问内存泄露与内存溢出的区别(CSDN上),而且后面还有一大堆的跟帖在用不同形式的语言予以解答,我看了以后思绪万千啊。内存泄露是导致内存溢出的原因之一,说他们的区别纯属无稽之谈。要解释什么是内存泄露还真是个费事的活,我用一个例子来解释下:

  • 如果是内存泄漏,可进一步通过工具查看泄漏对象到 GC Roots 的引用链。于是就能找到泄漏对象是通过怎样的路径与 GC Roots 相关联并导致垃圾收集器无法自动回收它们的。掌握了泄漏对象的类型信息,以及 GC Roots 引用链的信息,就可以比较准确地定位出泄漏代码的位置。 
  • 如果不存在泄漏,换句话说就是内存中的对象确实都还必须存活着,那就应当检查虚拟机的堆参数(-Xmx 与-Xms),与机器物理内存对比看是否还可以调大,从代码上检查是否存在某些对象生命周期过长、持有状态时间过长的情况,尝试减少程序运行期的内存消耗。 

  1. package outofmem;

  2. import java.util.ArrayList;
  3. import java.util.List;

  4. /**
  5.  * outofmemoryerror:其中之一
  6.  * 设置虚拟机堆的参数最小-Xms与最大-Xmx一样,避免堆自动扩展
  7.  * -Xms5m -Xmx5m
  8.  * 测试内存溢出
  9.  */

  10. public class TestMemOverflow {
  11.     static class OOMObject{
  12.         
  13.     }
  14.     public static void main(String[]args){
  15.         List<OOMObject>list= new ArrayList<OOMObject>();
  16.         int i=0;
  17.         while(true){
  18.             list.add(new OOMObject());
  19.             System.out.println(i++);
  20.         }
  21.         
  22.     }

  23. }

上面的代码会不停的往list中添加数据,当我们的堆空间不足时,就会报OOM的错误,如下:

  1. Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
  2.     at java.util.Arrays.copyOf(Unknown Source)
  3.     at java.util.Arrays.copyOf(Unknown Source)
  4.     at java.util.ArrayList.ensureCapacity(Unknown Source)
  5.     at java.util.ArrayList.add(Unknown Source)
  6.     at outofmem.TestMemOverflow.main(TestMemOverflow.java:20)

当堆空间不足的时候,JVM会进行垃圾回收,但是垃圾回收时却发现这些对象都是有用的,不能回收。我们可能会考虑增大堆空间大小,可是这还是于是无补,因为我们有个死循环。这种情况其实就是内存泄露的一个简单例子,简而言之,如果是内存泄露引起的OOM,那肯定是我们代码有问题,需要修正代码。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

0

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广