當你從c&c++轉到一門具有垃圾回收功能的語言時,程序員的工作就會變得更加容易,因為你用完對象,他們會被自動回收,但是,java程序員真的不需要考慮內存泄露嗎? 其實不然
1.舉個例子-看你能否找出內存泄漏
import java.util.Arrays;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 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); } }
1.1原因分析
上述程序并沒有明顯的錯誤,但是這段程序有一個內存泄漏,隨著GC活動的增加,或者內存占用的不斷增加,程序性能的降低就會表現(xiàn)出來,嚴重時可導致內存泄漏,但是這種失敗情況相對較少。
代碼的主要問題在pop函數,下面通過這張圖示展現(xiàn)
假設這個棧一直增長,增長后如下圖所示
當進行大量的pop操作時,由于引用未進行置空,gc是不會釋放的,如下圖所示
從上圖中看以看出,如果棧先增長,在收縮,那么從棧中彈出的對象將不會被當作垃圾回收,即使程序不再使用棧中的這些隊象,他們也不會回收,因為棧中仍然保存這對象的引用,俗稱過期引用,這個內存泄露很隱蔽。