Chinaunix首页 | 论坛 | 博客
  • 博客访问: 183047
  • 博文数量: 57
  • 博客积分: 2215
  • 博客等级: 大尉
  • 技术积分: 635
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-09 15:47
个人简介

非淡泊无以明志,非宁静无以致远

文章分类

全部博文(57)

文章存档

2013年(12)

2011年(15)

2010年(30)

我的朋友

分类: Java

2013-11-19 00:44:26

什么是内存泄露

看到网上有很多人都在问内存泄露与内存溢出的区别(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,那肯定是我们代码有问题,需要修正代码。




阅读(508) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~