zoukankan      html  css  js  c++  java
  • 07.消除过期对象的引用

    前言

    《Effective Java》中文第三版,是一本关于Java基础的书,这本书不止一次有人推荐我看。其中包括我很喜欢的博客园博主五月的仓颉,他曾在自己的博文《给Java程序猿们推荐一些值得一看的好书》中也推荐过。加深自己的记忆,同时向优秀的人看齐,决定在看完每一章之后,都写一篇随笔。如果有写的不对的地方、表述的不清楚的地方、或者其他建议,希望您能够留言指正,谢谢。

    《Effective Java》中文第三版在线阅读链接

    是什么

    过期对象的引用:指的是永远不会再被解除的引用。为什么会出现这样的情况,这是因为我们的栈在显示增长,然后再收缩,那么从栈中弹出来的对象将不会被当做垃圾回收,即使使用的栈的程序不再引用这些对象,它们也不会被回收。因为,栈内部维护着对这些对象的过期引用。

    没有消除过期对象实例,代码如下:

    /**
     * @author gongguowei01@gmail.com
     * @since 2020-01-19
     */
    public class Stack {
    
        public Object[] elements;
    
        public int size = 0;
    
        private static final int DEFAULT_VALUE = 16;
    
        public Stack() {
            elements = new Object[DEFAULT_VALUE];
        }
    
        public void push(Object e) {
            ensureCapacity();
            elements[size++] = e;
        }
    
        public Object pop() {
            if (0 == size) {
                throw new EmptyStackException();
            }
            return elements[--size];
        }
    
        public void ensureCapacity() {
            if (elements.length == size) {
                elements = Arrays.copyOf(elements, 2 * size + 1);
            }
        }
    }
    

    上方代码测试实例如下

    /**
     * @author gongguowei01@gmail.com
     * @since 2020-01-19
     */
    public class Test {
        public static void main(String[] args) {
            Stack stack = new Stack();
    
            stack.push("1");
    
            stack.push("2");
    
            stack.pop();
    
            stack.push("3");
        }
    
    }
    

    运行结果如下
    在这里插入图片描述
    当我们调用pop()方法时,size变为1,但是elements数组中还存在过期对象“1”的引用。

    消除过期对象的引用,代码实例如下

    /**
     * @author gongguowei01@gmail.com
     * @since 2020-01-19
     */
    public class Stack02 {
        public Object[] elements;
    
        public int size = 0;
    
        private static final int DEFAULT_VALUE = 16;
    
        public Stack02() {
            elements = new Object[DEFAULT_VALUE];
        }
    
        public void push(Object e) {
            ensureCapacity();
            elements[size++] = e;
        }
    
        public Object pop() {
            if (0 == size) {
                throw new EmptyStackException();
            }
            Object result = elements[--size];
            //消除过期对象引用
            elements[size] = null;
            return result;
        }
    
        public void ensureCapacity() {
            if (elements.length == size) {
                elements = Arrays.copyOf(elements, 2 * size + 1);
            }
        }
    }
    
    

    哪里用

    在有可能出现内存泄露的场景

    • 缓存
    • 自己管理内存的场景
    • 监听器和其他回调

    总结

    不消除过期对象的引用,将会引起内存泄露,内存泄漏通常不会表现为明显的故障,所以它们可能会在系统中保持多年。 通常仅在仔细的代码检查或借助堆分析器(heap profiler)的调试工具才会被发现。 因此,学习如何预见这些问题,并防止这些问题发生,是非常值得的。

  • 相关阅读:
    遇到项目上面有叉,但是找不到错误的原因
    遇到build的问题
    遇到scan configurtation CDT builder等的错误
    遇到attemp to invoke virtual method
    遇到looper之类关于消息循环的
    Linux与Windows信息交互快捷方法
    并行查询
    PostgreSQL 事务管理的MVCC
    Linux安装memcached
    Linux 安装 Redis
  • 原文地址:https://www.cnblogs.com/gongguowei01/p/12215831.html
Copyright © 2011-2022 走看看