我們用java管理內(nèi)存是十分容易的,因?yàn)閖vm會幫我管理內(nèi)存的釋放,但是這不意味著我們不用擔(dān)心內(nèi)存的事情了
造成內(nèi)存泄漏的地方一般來說有三個(gè):
- 過期對象的引用
- 緩存
- 監(jiān)聽器和其他的回調(diào)
過期對象的引用
public class Stack {
private static final int DEFAULT_INITIAL_CAPACITY = 16;
private Object[] elements;
private int size = 0;
public Stack() {
elements = new Object[DEFAULT_INITIAL_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);
}
}
}
這個(gè)例子看起來是沒有任何問題的,可以通過編譯,但是會造成內(nèi)存泄漏!
緩存
解決辦法是 所有的緩存我們設(shè)置一個(gè)過期時(shí)間, 過期了就將對象進(jìn)行銷毀
監(jiān)聽器和回調(diào)
內(nèi)存泄漏第三個(gè)常見來源是監(jiān)聽器和其他回調(diào)续搀,如果客戶端在你實(shí)現(xiàn)的API中注冊回調(diào),卻沒有顯示的取消菠净,那么就會積聚禁舷。需要確保回調(diào)立即被當(dāng)作垃圾回收的最佳方法是只保存他的若引用毅往,例如將他們保存成為WeakHashMap中的鍵牵咙。