5.消除过期的对象引用

java是具有垃圾回收功能的语言,那么我们就不再需要去考虑内存管理的事情了呢?当然不是,当你不小心时,也会导致内存泄漏

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];
    }
    
    private void ensureCapacity(){
        if(elements.length == size){
            Object[] oldElements = elements;
            elements = new Object[2*elements.length + 1];
            System.arraycopy(oldElements, 0, elements, 0, size);
        }
    }
}

 当使栈先是增长,然后再收缩,那么,从栈中弹出来的对象将不会被当做垃圾回收,即使使用栈的客户程序不在引用这些对象,它们也不会被回收。这是因为,栈内部维护着对这些对象的过期引用。所谓过期的引用,是指永远也不会被解除的引用。例如一些容器你也可能忘了去清理。

应该这样做:

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

    内存泄漏的另一个常见的来源是缓存。有时候,当我们将一个对象的引用放入了缓存,很容易遗忘它。有两种常用的方式去解决:

 1.利用WeakHashMap。

2.LinkedHashMap,利用它的removeEldestEntry也可以实现对缓存的清除

关于WeakHashMap的知识,介绍:

HashMap:   https://blog.csdn.net/hxpjava1/article/details/55670439

WeakHashMap: https://www.cnblogs.com/redcreen/archive/2011/02/15/1955289.html

                            https://blog.csdn.net/u012129558/article/details/51980883

WeakHashMap和HashMap实现基本相同,最关键是有一个 ReferenceQueue<K> queue 保存需要清除的key和  expungeStaleEntries()  真正清除键值对。

猜你喜欢

转载自blog.csdn.net/qq_27469549/article/details/80424051