2、Java的內存泄漏
什麼是內存泄漏呢?程序運行過程中會不斷分配內存空間,那些不再使用的內存空間應該即時被回收,從而保證系統可以再次使用這些內存空間,如果存在無用的內存沒有被回收回來,那就是內存泄漏。
對於Java程序來說,所有不可達的對象都由垃圾回收機制負責回收,因此程序員不需要考慮這部分的內存泄漏。但如果程序中有一些Java對象,它們處於可達狀態,但程序以後永遠都不會再訪問它們,那麼它們所佔用的空間也不會被回收,它們所佔用的空間也會產生內存泄漏。
//ArrayList中remove(int index)方法源代碼
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work ①
return oldValue;
}
上面①行代碼就是爲了避免垃圾回收機制而書寫的代碼。如果沒有這行代碼,這個方法就會產生內存泄漏,原因:刪除一個對象,但該對象所佔用的內存空間不會釋放。
例如,試圖刪除ArrayList最後一個元素,假設該ArrayList底層的數組長度爲8,裏面裝有4個元素,此時內存中的分配示意圖如下所示。
當刪除ArrayList的最後一個元素時,要刪除的元素所在的index = size - 1。但是如果不執行①行代碼,ArrayList在內存中的分配示意圖如下所示。下圖中的4個元素一直引用內存中原來的對象,那麼這個對象將一直處於可達狀態。但是對於ArrayList而言,它的size等於3,也就是說,ArrayList認爲只有3個元素,因此永遠也不可能訪問底層數組的第4個元素。對於程序本身來說,這個對象已經變成了垃圾,但對於垃圾回收機制來說,這個對象依然處於可達狀態,因此不會回收它,這就產生了內存泄漏。