过期的对象引用

简介: 内存泄漏-如果一个栈显示增长,然后再收缩,那么,从栈中弹出来的对象将不会被当做垃圾回收,即使使用的栈的程序不再引用这些对象,它们也不会被回收.这是因为,栈内部维护着对这些对象的过期引用.

消除过期的对象引用

修正前

public class Stack {

    public Object[] elements;
    
    public int size = 0;
    
    private static final int DEALULT_VLAUE = 16;

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

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

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

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

}

这段程序中并没有很明显的错误.无论如何测试,它都会成功通过每一项测试.
但是! 这段程序有一个"内存泄漏"

解析

       // elements="Stack@539"
        Stack stack = new Stack();

        // elements[0]="1" size=1
        stack.push("1");

        // elements[0]="1" elements[1]="2" size=2
        stack.push("2");

        // elements[0]="1" elements[1]="2" size=1 pop="2"
        Object pop = stack.pop();

        // elements[0]="1" elements[1]="3" size=1
        stack.push("3");

从上方可以看出如果pop后没有重新push那么elements对象还在引用已经删除的对象


内存泄漏-如果一个栈显示增长,然后再收缩,那么,从栈中弹出来的对象将不会被当做垃圾回收,即使使用的栈的程序不再引用这些对象,它们也不会被回收.这是因为,栈内部维护着对这些对象的过期引用.
过期引用-,是指永远也不会再被删除的引用.


修正后

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

解析

       // elements="Stack@539"
        Stack stack = new Stack();

        // elements[0]="1" size=1
        stack.push("1");

        // elements[0]="1" elements[1]="2" size=2
        stack.push("2");

        // elements[0]="1" size=1 pop="2"
        Object pop = stack.pop();

        // elements[0]="1" elements[1]="3" size=1
        stack.push("3");
相关文章
|
3月前
|
C++
记录一次循环引用的问题
记录一次循环引用的问题
|
7月前
|
缓存 NoSQL Java
Java实现redis缓存效果变量过期
Java实现redis缓存效果变量过期
73 0
|
7月前
|
Java
如何判断一个对象是否存活?
如何判断一个对象是否存活?
48 0
|
17天前
|
缓存 算法 Java
如何实现缓存与LRU算法以及惰性过期
如何实现缓存与LRU算法以及惰性过期
29 1
|
9月前
|
存储 缓存 算法
13-大厂面试题:为什么要垃圾回收以及如何判断对象可以回收
接下来我们正式进入第二个系列,关于垃圾回收以及优化。
82 0
13-大厂面试题:为什么要垃圾回收以及如何判断对象可以回收
|
9月前
|
算法 Java 关系型数据库
引用计数 vs 根可达算法:深入比较对象存活判定
引用计数 vs 根可达算法:深入比较对象存活判定
138 0
|
缓存 算法 Java
内存管理:判断对象是否存活
在堆里面存放着 Java 世界中几乎所有的对象实例,垃圾收集器在对 Java 堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着,哪些已经“死去”(“死去”即不可能再被任何途径使用的对象)。 有两种判断对象是否存活的算法:引用计数算法、可达性分析算法。
107 0
内存管理:判断对象是否存活
|
算法 Java Python
26. 如何判断一个对象是否存活?(或者GC对象的判定方法)?
26. 如何判断一个对象是否存活?(或者GC对象的判定方法)?
75 0
26. 如何判断一个对象是否存活?(或者GC对象的判定方法)?
|
算法 Java C#
jvm(6) -- 如何判定对象为垃圾对象(是否存活)
jvm(6) -- 如何判定对象为垃圾对象(是否存活)
106 0
jvm(6) -- 如何判定对象为垃圾对象(是否存活)
|
缓存 Java 关系型数据库
强引用、软引用、弱引用、幻象引用有什么区别和使用场景
强引用、软引用、弱引用、幻象引用有什么区别和使用场景
157 1