2012-09-26 16 views
1

我明白世代垃圾收集HotSpot JVM如何使用作品。我們有一個返回靜態數據的列表的方法,沿着我正在考慮重寫本的用於靜態數據的短期與長期生活

public List<String> getList() { 
    List<String> ret = new ArrayList<String>(); 
    ret.add("foo"); 
    ret.add("bar"); 
    return ret; 
} 

以線條爲

private static List<String> list = null; 
... 
public List<String> getList() { 
    if (list == null) { .. initialize here .. } 
    return list; 
} 

這隻會一次創建列表。這個單一的列表實例最終將進入終身的一代。由於這是一個相當大的應用程序,在許多地方使用這種設計模式意味着在時代中有很多這樣的靜態列表 - 增加了應用程序的內存使用量。

如果我們每次都遵循創建和返回新列表的模式,那麼在垃圾收集之前,這個列表永遠不會使它從伊甸園中出來。將涉及更多的工作 - 不得不創建並填寫清單,並從事垃圾收集工作 - 但由於清單持續時間不長,我們將整體使用較少的內存。

這個問題本質上更具學術性,因爲任何一種模式都可行。存儲靜態列表會增加內存使用量,並且每次創建列表都會增加工作量,但數量不會太大。使用哪種模式可能取決於許多因素 - 列表使用頻率,應用程序承受多少內存壓力等等。您會選擇哪種模式,爲什麼?

+0

哦時間與空間永無止境,權衡:P – gtgaxiola

+0

有一點要考慮的是,存儲靜態列表是更容易出錯 - 呼叫者該方法可以修改返回值等。一般來說,您不應該嘗試智取GC。 –

+1

當您存儲長期數據時,請確保它是不可變的。這裏和那裏的幾個列表不會讓你的工作集大,而且你可能已經有了長期的對象(服務,DAO等等)。 –

回答

4

存儲靜態列表將極少量的提高內存的使用

它會使用更多的空間時,有它沒有真正的需要。如果有一個用法,它將是相同的。但是如果你有多個副本,靜態版本更有效率。

通常情況下,它不是最好的情況會殺了你,它是最糟糕的情況。在最糟糕的情況下,會有大量數百萬?的集合副本。

+0

確實使用的內存量是相同的,因爲它是相同的內容列表。踢球者是存儲器正在使用的時間量;如果我保留一個靜態列表,那麼這個內存是爲jvm的生命保留的,而一個短命的列表可以被垃圾收集。關於最糟糕的情況很好,但我沒有考慮到這一點 – rhollencamp

0

正如Peter Lawrey所指出的那樣,在非靜態的情況下,當GC等待完成它的工作時,有時候你會使用比需要更多的內存。

我會專注於更可讀的東西。對我來說,番石榴的ImmutableList.ofstatic final字段中立即表示這個數據不會改變。

(或者Collections.unmodifiableList(Arrays.asList(...))如果你不想番石榴)