Effective Java 之-----消除过期的对象引用
public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_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); } } }
程序中存在内存泄露: 如果一个栈先增后减,那么在栈中弹出的对象将不会被当做垃圾回收,即使使用栈的程序不再引用这些对象,他们也不会被回收。
修复方法很简单:手动清除这些引用即可:
public Object pop(){ if(size == 0){ throw new EmptyStackException(); } Object result = elements[--size]; elements[size] = null; return result; }
一般而言,只要是类自己管理内存,就应该警惕内存泄露问题。
内存泄露的另外几个常见来源是缓存,监听器及其他回调。
处理方式:
1、起一个后台线程来完成,或者给缓存添加新条目时顺便清理;
2、LinkedHashMap类可以利用他的removeEldestEntry方法实现,对于更复杂的缓存,必须直接使用java.lang.ref;
3、确保回调立即被当做垃圾回收的最佳方法是 只保存他们的弱引用,例如,只将他们保存成WeakHashMap中的键。 (只有当所要的缓存项的生命周期是由该键的外部引用而不是由值决定时,WeakHashMap才有用处)