Java中ArrayList 自動擴容的內存上的具體過程是怎樣的?
Java中ArrayList 自動擴容的內存上的具體過程是怎樣的?為了答這個題,又去溫習了一遍ArrayList的源碼,姑且說下。。
JAVA中的很多基本數據結構都有動態擴容機制,比如hashMap,arraylist,之前說過了hashMap的擴容,現在說下arraylist的。。
arraylist的擴容發生在add()方法過程中,如下圖,先返回一個最新的size+1的數組,然后把加入的元素放入其中,如下圖:

上圖中的ensureCapacityInternal方法,主要是調用grow()方法,如下所示:

在grow方法中定義了一個新的數組容量newCapacity=oldCapacity +(oldCapacity >>1),>>符號代表左移一位,也就是除以2,換句話說新的容量擴容變為原來的1.5倍大小!然后將舊的所有元素通過使用Arrays.copyOf方法復制到新的數組中!

如下面的代碼所示:Arrays.copyOf方法內部是調用的native方法System.arraycopy();這個方法會在內存中創建一個新的數組,所以在擴容之后,返回的通常是一個新創建的數組,來替換原來的數組。

一般來說,list的自動擴容有兩個方面的問題:
①,性能:每次擴容都需要創建新的數組,并且復制原有數據,如果一個arraylist存儲的數據過大,也就代表著擴容次數多,而且對內存有很大的占用!
②,線程不安全:因為調用add方法中,有++操作,可能會在多線程環境下引起數組中元素為空,數據被覆蓋等問題,所以在多線程環境下,arrayList需要改為Collections.synchonizedList()來獲取一個安全的list實例!


