您的位置:首页 > 其它

第6条 创建和销毁对象——消除过期的对象引用

2016-05-03 15:01 260 查看
1、如果一个栈先是增长,然后再收缩,那么从栈中弹出来的对象将不会被当作垃圾回收,即使使用栈的程序不再引用这些对象,它们也不会被回收。这是因为,栈内部维护着对这些对象的过期引用。所谓的过期引用是指永远不会被解除的引用。给出下面简单的栈的实现的例子:

publicclass Statck{
private Object[] elements;
private int size = 0;
private static final intDEFAULT_INITIAL_CAPACITY = 16;

public Statick(){
elements= new Object[DEFAULT_INITIAL_CAPACITY];
}

public void push(Object e){
ensureCapacity();
elements[size++]= e;
}

public Obeject Pop(){
if(size== 0)
thrownew EmptyStackException();
returnelements[--size];
}

private void ensureCapacity(){
if(elements.length== size)
elements= Arrays.copyOf(elements,2*size+1);
}
}

      在上例中,凡是在elements数组的“活动部分”之外的任何引用都是过期的。活动部分是指elements中下标小于size的那些元素。

2、在Stack中解决过期引用的方法就是在把对象推出的时候,把相应地栈引用清空即可,Pop方法的修订版如下:

publicObeject Pop(){
if(size == 0)
thrownew EmptyStackException();
Object result = elements[--size];
elements[size] = null;
return result;
}

        尽管这样做是有效的,但是这样做是不必要的,也不是我们所期望的,因为这样会把程序代码弄的很乱。清空对象引用应该是一种例外,而不是一种规范。消除过期引用最好的方法是让包含该引用的变量结束其生命周期。如果是在最紧凑的作用域范围内定义每一个变量,这种情形就会自然而然地发生,如将局部变量的作用域最小化。

3、常见内存泄漏的来源

       1)一般而言,只要类自己管理内存,如Stack类,解决方法就是把这种情况告知垃圾回收器:一旦数组元素变成了非活动部分的一部分就手工清空这些数组元素。

       2)缓存的使用。解决方法是:只要在缓存之外存在对某个项的键的引用,该项就有意义,那么就可以用WeakHashMap代表缓存;当缓存中的项过期后,它们就会自动被删除。

       3)监听器和其他调用。确保回调立即被当作垃圾回收的最佳方法是只保存它们的弱引用,例如,只将它们保存成WeakHashMap中的键。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: