public class Stack {
private Object[] elements;
private int size=0;
public Stack(int initialsCapacity)
{
this.elements=new Object[initialsCapacity];
}
public void push(Object e)
{
ensureCapacity();
elements[size++]=e;
}
public Object pop() throws Exception
{
if(size==0)
{
throw new Exception();
}
return elements[size--];
}
private void ensureCapacity() {
// TODO Auto-generated method stub
if(elements.length==size)
{
Object[] oldElements=elements;
elements=new Object[elements.length*2+1];
System.arraycopy(oldElements,0,elements,0,size);
}
}
}
effective java上说有内存泄露,希望高人指点下,谢!!!

解决方案 »

  1.   

    对象使用完后要 将其=null
      

  2.   

    是,不过为什么啊,如果不置为null,那个下一个push进来的对象会覆盖前一个elements,使指向改变,导致堆中new出来的对象会被回收,所以应该也不会有问题啊,
      

  3.   

    囧啊,书上都已经说很明白了,还用问么大意就是说,你先push,然后pop,在无效的element区域,保留了原有对象的句柄,导致gc认为还有一个显示的引用,所以不会释放对应内存;
    举例:push 10个对象,然后pop8个,目前有效的就两个对象,但是pop之后,element数组中下标为2-9的8个对象引用还在,所以,这8个对象不会被gc释放
      

  4.   

    代码给我的感觉是,public void push(Object e) 入栈操作。public Object pop() 出栈操作。
    但是这个出栈操作,并没有真正的弹出Object,只是将Object返回了。
    这个对象依然存在,因为elements对象数组依然持有那个弹出栈的对象的引用。
    所以不会被回收。这样改下试试: public Object pop() throws Exception {
    Object tmp;
    if (size == 0) {
    throw new Exception();
    }
    tmp = elements[size--];
    elements[size] = null;
    return tmp;
    }
    具体可以参照
    java.util.Stack 的 pop() 方法。
      

  5.   

    问题处在下面的方法中:
    private void ensureCapacity() {
      if(elements.length==size) { 
        Object[] oldElements=elements;
        elements=new Object[elements.length*2+1]; 
        System.arraycopy(oldElements,0,elements,0,size);//System.arrayCopy 实现数组的深拷贝,并不是复制对象的引用,那么这里的oldElements你没有去释放它,每调用一次push就多余一些垃圾数据,这里除非换个实现,要么自己将oldElements释放
      }
    }
      

  6.   

    有些分歧。
    我的理解是:
    根据构造函数的实现: elements=new Object[initialsCapacity];
    elements指向了 new Object[initialsCapacity]那个数组对象。
    在每次push对象的时候,调用ensureCapacity,判断是否长度已经超过了初始化(initialsCapacity)的容量。
    如果超过了,
    则用临时变量Object[]oldElements指向 原来的数组对象,
    然后创建(elements.length*2+1)的数组,将其引用赋给了elements。
    最后,通过System.arraycopy将原来的数组对象的数据拷贝到新创建的数组对象。
    方法返回后,原来的数组的对象应该可以被回收了。
    因为没有引用指向它了。
      

  7.   

    effective java好书啊,可惜还没修炼到可以看此书的程度
      

  8.   


    bzwm的观点是正确的,原先数组对象不再被引用,可以回收
      

  9.   

    答:关键是:
    public Object pop() throws Exception 

    if(size==0) 

    throw new Exception(); 

    return elements[size--]; //这是问题的核心所在.

    要求是的从"栈中移走元素",而不是仅仅返回它.因此:
    要:
    Object o=elements[size]; 
    elements[size]=null; //这才是真正栈中移走它.
    size--;
    注:若程序中不是使用的数组来做栈,而是List之类,更是要注意是:移走 而不是仅仅 返回一个元素
      

  10.   

    effective java 这两天 有点热