effective java读书笔记三

第5条:消除过期的对象引用


考虑下面的代码: 
  
// Can you spot the "memory leak"? 
  public class Stack { 
      private Object[] elements; 
      private int size = 0; 

      public Stack(int initialCapacity) { 
          this.elements = new Object[initialCapacity]; 
      } 

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




      public Object pop() { 
          if (size == 0) 
              throw new EmptyStackException(); 
          return elements[--size]; 
      } 

      /** 
      * Ensure space for at least one more element, roughly 
      * doubling the capacity each time the array needs to grow. 
      */ 
      private void ensureCapacity() { 
          if (elements.length == size) { 
              Object[] oldElements = elements; 
              elements = new Object[2 * elements.length + 1]; 
              System.arraycopy(oldElements, 0, elements, 0, size); 
          } 
      } 
  }


如果一个栈先增长然后再缩小,那么从战栈中弹出来的对象并不会被回收,即使使用这个栈的程序不再引用它们.这是因为栈内部维护者对这些对象的过期引用。所谓的过期引用
是指永远也不会再被解除的引用。这种情况可能会导致内存泄露。
要想修复这一问题也很简单:一旦对象引用已经过期,只需清空这些引用即可。例如上例中只要一个单元被弹出那么指向它的引用就过期了,pop方法修正后如下:
public Object pop() { 
        if (size==0) 
            throw new EmptyStackException(); 
        Object result = elements[--size]; 
        elements[size] = null; // Eliminate obsolete reference 
        return result; 
   }


清除过期引用的另一个好处是,如果以后它们又被错误的接触引用,则程序会立即抛出空指针异常,而不是悄悄的错误运行下去。



注意:
1、不必过分小心,例如对每一个对象引用一旦程序不用就立即清空。这样会使代码很乱同时降低程序效率。
2、一般而言,只要一个类自己管理它的内存,程序员就要警惕内存泄露的问题。
3、内存泄露的另一个常见来源是缓存。

关于java中的几种引用关系,参考:Java基础 之软引用、弱引用、虚引用



第6条:避免使用才终结函数
1、终结函数(finalizer)通常是不可预测的,危险的,一般情况也是不必要的。
2、终结函数会导致不稳定的行为、更差的性能和移植性。
3、由于终结函数不能确保被即使的执行,所以对于时间关键的任务不应该使用终结函数来完成。例如:关闭已打开的文件。
4、我们不应该依赖终结函数来更新关键性的永久状态.例如:释放共享资源(比如数据库)上的永久锁。

但有两种情况下可以使用

1.当对象所有者忘记调用显示的终结方法(如connection,inputstream,outputstream的close方法和Timer中的cancel方法,这只是一种保险的方法

  完全可以由程序员的细心避免的,所以使用这些类的时候千万要记住调用显示的终结方法

2本地对象  也就是其他语言编写的对象托管给java管理,当垃圾回收器回收java对象时,那些本地对象占用的资源是不会回收的,所以这里就需要调用对象的finalizer方法


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值