坚持英文原版阅读.
清除过时对象的引用。
这是导致内存泄漏的一个原因。
一个简单的出栈代码:
public class Stack{
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY=16;
public Stack(){
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
//入栈
public Object push(Object o){
ensureCapacity();
elements[size ++] = o;
}
//出栈
public Object pop(){
if(size == 0){
throw new EmptyStackException();
}
Object result = elements[--size];
return result;
}
//扩容
private void ensureCapacity(){
if(elements.length == size){
elements = Arrays.copyOf(elements, 2 * size -1);
}
}
}
在调用pop()出栈方法后,elements[--size]中的引用并没有被清除,如果new Stack()的作用域较大,生命周期长,可能会出现内存溢出的情况。
正解:
//出栈
public Object pop(){
if(size == 0){
throw new EmptyStackException();
}
Object result = elements[--size];
elements[size] = null;//Eliminate
return result;
}
对比JDK源码:
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
public synchronized void removeElementAt(int index) {
modCount++;
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
else if (index < 0) {
throw new ArrayIndexOutOfBoundsException(index);
}
int j = elementCount - index - 1;
if (j > 0) {
System.arraycopy(elementData, index + 1, elementData, index, j);
}
elementCount--;
elementData[elementCount] = null; /* to let gc do its work */
}
其他可能出现内存溢出的情况:
1.caches.缓存,对象放入缓存后忘记清除。
2.listeners and other callbacks.监听和回调。这种情况,笔者暂未遇到。