2009-02-22 66 views
11

明確()IMPL我擔心這是一個非常愚蠢的問題,但在這裏有雲:在Java中的LinkedList的

爲什麼在Java中的默認的LinkedList實現clear方法懶得走路的列表,並解開所有的節點?爲什麼不解開標題並將列表的其餘部分連接在一起 - GC將會得到它,不是嗎?

這裏的方法:

/** 
* Removes all of the elements from this list. 
*/ 
public void clear() { 
    Entry<E> e = header.next; 
    while (e != header) { 
     Entry<E> next = e.next; 
     e.next = e.previous = null; 
     e.element = null; 
     e = next; 
    } 
    header.next = header.previous = header; 
    size = 0; 
modCount++; 
} 

爲什麼走了?爲什麼不直接跳到header.next = header.previous = header;

我能想到的最好方法是幫助GC ...?這個鏈接http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html#997442表明這一點。

TIA ...

回答

18

他們的方法可以確保即使其他代碼仍持有到特定節點的引用,其他節點將GC'ed。

否則,即使對其中一個節點的單個外部引用也會阻止整個鏈的收集。另外,列表中的其他操作可能正在同時進行(例如,通過subList()Collections.unmodifiableList()迭代器的視圖),並且這確保了這些事物立即將列表視爲「空」。

+0

我都不同意,說外部代碼無法獲得對LinkedList $ Entry的引用......但是通過LinkedList $ ListItr間接你肯定可以......非常感謝! – overthink 2009-02-22 23:14:33

2

IIRC,這是在JDK6中進行的一項更改,以協助某些(代)GC算法的性能。通常,List本身和較舊的節點將比其他一些節點舊一代。年輕一代會更頻繁地收集,結果是在發現所有節點都是垃圾之前,年輕節點被複制。

所以這是一個小的性能優化。內存性能優化有點奇怪,因爲這通常不是引起問題的代碼,而是需要額​​外的時間來執行。

0

我只是在我的遊戲開發博客上猜測這個問題。感謝你的回答。我認爲節點暴露是一個值得懷疑的設計限制。同樣粗略的是,列表上的備用視圖(迭代器等)將依賴於節點解除鏈接來實現快速失敗。不要依賴這種副作用行爲,列表中的子視圖應該檢查修改計數。無論如何,我明白爲什麼他們現在仍然堅持下去。