Effective java2——内存泄露

JVM提供了垃圾回收器,java程序员再也不用像C/C++程序员一样整体为对象的清理工作而焦头烂额,但是并非说java中不存在内存泄露的情况,下面展示一个典型的内存泄露的例子。

使用数组作为底层数据结构实现一个Stack栈数据结构的容器,代码如下:

public class Stack{

   private Object[] elements;

   private int size = 0;

   private static final int DEFAULT_SIZE = 15;

   public Stack(){

        elements = new Object[DEFAULT_SIZE];

  }

public void push(Object o){

    ensureCapatity();

    elements[size++]=0;

 }

public Object pop(){

    if(size == 0){

       throw new EmptyStackException();

    }

   return elements[--size];

}

//如果栈已满,则将容量扩大一倍

public ensureCapatity(){

     if(elements.length == size){

        elements = Arrays.copyOf(elements,2*size + 1);

     }

   }

}

咋一看可能看不出什么问题,相信很多人也写过这样的代码,如果使用大量数据测试就会发现内存持续上升,如果把测试数据增大一倍,发现内存也跟着增长一倍,这就产生了典型的内存泄露情况。仔细研究出栈pop()操作,你会发现,栈中存在大量的无法被引用的对象,因为出栈之后并没有将元素标记为不再使用,这些在size之后的元素就成了无法被访问的无效引用对象,但是由于stack栈对象本身还是有效引用,因此这些无效的引用无法被垃圾回收器回收,造成内存泄露。

解决上述例子内存泄露的方法也很简单,重新pop()方法如下:

public Object pop(){

   if(size==0){

     throw new EmptyStackException();

  }

  Object result = elements[--size];

  elements[size] == null;//将已经出栈的元素置为null,垃圾回收器就会清理这些对象

   return result;

}

java中经常引起内存泄露的情况及解决方法:

(1)长生命周期的集合容器对象中存在大量无效引用的短生命元素对象:将容器中不再使用的对象标记为null,以防止产生无法访问的无效引用。

(2)通知的资源访问,如namingservice,cache等等:定时清理;使用WeakRefrence弱引用;使用WeakHashMap容器等。

(3)监听器和callback回调函数。使用WeakReference弱引用;使用WeakHashMap容器等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值