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

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中的键。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值