2013-05-30 50 views
-4

與Vector相比,使用ArrayList佔用的內存少嗎?當Vector向量達到最大大小時,Vector讀取的Vector會將內部數組大小加倍,因爲ArrayList只能減少一半?這是一個真實的陳述嗎?當我沒有用initialcapacity和capacityIncrement的值聲明Vector時,我需要答案。ArrayList VS Vector JVM內存使用情況

+4

向量被認爲是過時的,所以沒有什麼理由使用它們。 JDK帶有源代碼,所以快速查看'add'方法應該會給你答案。 – assylias

回答

0

要回答原始問題: ArrayList默認情況下會將容量增加一半的當前容量。但是,程序可能隨時調用ensureCapacity將容量設置爲適當的大值。

Vector默認情況下會增加一倍的容量。但是,有一個構造函數允許設置增長量。使用小的增長值會對性能產生負面影響。此外,您實際上可以獲得更少的容量,因爲每次增長都需要在內存中存在一段重複的數組以在短時間內存在。

在評論中,OP曾表示:龐大的數據集

應用拉動,我們目前面臨的內存不足,由於杏堆大小

首先,無論是VectorArrayList將拋出一個OutOfMemoryError如果程序試圖增加容量超過設定的限制。您需要確保OOME不是源自Vector類的hugeCapacity方法。如果是這種情況,那麼也許你可以試試LinkedList

二,你目前的堆大小是多少?默認的JVM堆大小非常小。其目的是爲了避免完整GC中的暫停或斷斷續續的行爲對applet的用戶變得明顯。但是,對於相當複雜的應用程序或相當愚蠢的服務,堆大小通常也很小。可以使用-Xmx JVM arg來增加堆大小。

+0

現在的問題是我們在應用程序中定義了一個向量,並且沒有設置任何容量。所以矢量默認情況下會增長。此外,我們正在從數據庫中提取大量數據集。我們不知道數據集的大小,它取決於特定場景的數據。我們經常遇到OOM問題,並且在分析堆轉儲時,供應商團隊建議當OOM發生時,該特定TXN的Vector對象使用堆大小的75%。我們正在嘗試各種方法來減小此向量的大小,並且用ArrayList替換它是其中一個建議。 – EVS

+0

我們有多個JVM,而OOM只發生在一個JVM中,而不是全部發生。每個JVM的堆大小爲1.2 GB – EVS

+0

如果小幅增加可以解決問題,則可以將堆增加到1.2 GB以上。或者也許可能不會一次提取所有數據?也許保持光標與數據庫打開? –

2

是的,你在內部數組的內存分配方面是正確的:

內部,無論是ArrayList和Vector守住使用數組的內容。當一個元素被插入到一個ArrayList或一個Vector中時,如果對象在空間不足時需要擴展它的內部數組。 Vector默認將其數組大小加倍,而ArrayList將數組大小增加50%。

修正

它並不總是那麼這些向量將翻倍的能力。這可能只是增加其規模高達在構造函數中提到的增量:

public Vector(int initialCapacity, int capacityIncrement) 

在成長方法的邏輯是,增加容量加倍,如果沒有提到增量,否則使用將按capacityIncrement,這裏是矢量的碼長方法:

private void grow(int minCapacity) { 
    // overflow-conscious code 
    int oldCapacity = elementData.length; 
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ? 
            capacityIncrement : oldCapacity); 
    if (newCapacity - minCapacity < 0) 
     newCapacity = minCapacity; 
    if (newCapacity - MAX_ARRAY_SIZE > 0) 
     newCapacity = hugeCapacity(minCapacity); 
    elementData = Arrays.copyOf(elementData, newCapacity); 
} 
+0

謝謝您的確認。 – EVS

+0

我只是指向Vector的默認聲明,並沒有使用capacityIncrement限制的構造函數。 – EVS

1

VectorArrayList和沒有比較,因爲它們適合不同的用途。 Vector應該是一個併發安全List實現。但是,該類的設計存在嚴重缺陷,並且沒有爲最常見的迭代使用情況提供併發保證。

Vector本身很容易替換爲Collections.synchronizedList(new ArrayList())。結果當然包含與Vector相同的缺陷。 Vector應被視爲棄用。

使用Vector現在是理解Java和併發編程的天真標誌。不要使用它。

+0

謝謝,蒂姆。這是一箇舊的應用程序,它仍然使用矢量。該應用程序可以提取龐大的數據集,並且由於最大化堆大小,我們目前面臨內存不足的情況。因此,其中一個建議是使用ArrayList而不是Vectors。 – EVS

+0

你問錯了問題!當你說「最大化堆」時,我不得不問「堆的大小是多少?」你真的超過了4Gb的內存嗎?如果是這樣,你是否真的需要一次在內存中?如果您知道數據集的大小,爲什麼不恰當地設置初始容量? –

+0

Vector的使用不太可能是實際的問題。 向量是例如在移動Java上的最低可用動態大小列表。該cldc只有作爲一個動態大小的數組類型的數據存儲列表對象。 (cldc有一個列表類,但它不是你想要的列表)。它的cldc版本相當精簡併且沒有出錯,並直接從Object繼承。這是一個相當不錯的課,從來沒有給我任何內存問題,也不是太慢.. 仍然,完整的jdk向量不應該是大規模內存使用的罪魁禍首。 –