Effective Java 第6条: 消除过期的对象引用

示例:
你找的出来下面代码中的内存泄漏(memory leak)吗

public class Stack {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_ININTIAL_CAPACITY = 16;

    public Stack() {
        elements = new Object[DEFAULT_ININTIAL_CAPACITY];
    }

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

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

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

如果一个栈先增长,然后再收缩,那么pop出来的对象将不会被当做垃圾回收.
即使使用栈的程序不在引用这些对象,他们也不会被回收.
因为栈内部维护这这些对象的过期引用(永远不会再被解除的引用)

上面代码中,pop方法:

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

这里将一个元素弹出后,引用仍被栈内部保存着,所以需要手动将其消除:

  public pop() {
        if (size == 0) {
            throw new EmptyStackException();
        }

        Object result = elements[--size];
        elements[size] = null;  // Eliminate obsolete reference.
        return result;
    }

清除过期引用好处:

  • 避免内存泄漏
  • 避免错误处理引用, 会抛出NullPointException,而不是悄悄的继续运行,导致查不出bug.

清空对象引用应该是一种例外,而不是一种规范行为

消除过期引用的最好的方法:让包含该引用的变量结束在其生命周期.

Stack类自己管理内存.
一般而言,只要类是自己管理内存,程序员就应该警惕内存泄漏问题.一旦元素被释放掉,则该元素中包含的任何对象引用都应该被清空.

内存泄漏的另一个常见来源是缓存. 应该时不时清除缓存中没有用的项.(LinkedHashMap)

内存泄漏的第三个常见来源:监听器和其他回调. (只注册,未注销)

内存泄漏常见来源:

  • 过期引用
  • 缓存
  • 监听器和其他回调
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 如图所示的例子,这段程序中没有明显的错误,但是存在一个隐藏的问题(“内存泄漏”),随着垃圾回收活动的增加,或者由于...
    郭_4d5f阅读 462评论 0 0
  • 虽然在Java语言中拥有垃圾收集(GC)回收程序,在创建对象后,不用程序员手动回收对象,但在某些情况下依然会造成内...
    QyQiaoo阅读 340评论 0 1
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,174评论 1 32
  • 今天要加油^0^~ 读新书 备课 健身
    赵芳_790d阅读 173评论 0 0
  • 사막에서 비행가가 고장을 일으킨지 여드레째 되는 날이었다. 나는 비축해 두었던 물의 마지막 남은 한 방...
    潇漫阅读 892评论 0 3