2009-02-22 6 views
11

에서 분명히() IMPL 나는이 정말 바보 같은 질문입니다 두려워하지만, 여기 간다 :자바의 LinkedList의

왜 자바의 기본 LinkedList의 구현에 명확한 방법은 목록을 걸어 모든 노드를 벗기기 귀찮게합니까? 왜 헤더를 풀고 목록의 나머지 부분을 연결 한 채로 두지 마십시오. 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의 $ 항목에 대한 참조를 얻을 수있는 방법은 없습니다 말, 동의하는 모든 설정했다 ...하지만 간접적 LinkedList의 $ ListItr을 통해 확인 할 수 ... 감사합니다 좋은 캐치! – overthink

+0

노드를 보유하고있는 것은 무엇입니까? Iterator 또는 subList이지만 유효하지 않으므로 계속 유지해야합니다. –

+0

@Tom :이 작업을 수행하지 않았다면 subList와 Iterator는 계속 작동하지만 콜렉션 프레임 워크는 fail-fast를 시도합니다 (그러나 보장하지는 않습니다). –

2

IIRC 이것은 특정 (세대 별) GC 알고리즘의 성능을 지원하기 위해 JDK6에서 변경 한 것입니다. 종종 List 자체 및 이전 노드는 다른 노드 중 일부보다 오래된 세대에있게됩니다. 젊은 세대는 더 자주 수집 될 것이고 그 결과 젊은 노드는 모든 노드가 쓰레기라는 것을 알기 전에 복사됩니다.

그래서 성능이 최적화되지 않았습니다. 메모리 성능 최적화는 약간의 시간이 걸리는 문제를 야기하는 코드가 아닌 점에서 조금 이상합니다.

0

저는 게임 개발 블로그에서 바로이 문제를 추측하고있었습니다. 답변 해주셔서 감사합니다. 노드 노출은 의심스러운 디자인 수당이라고 ​​주장합니다. 리스트 (반복자 등)에 대한 대체 뷰가 노드의 링크 해제에 의존하여 패스트 패스트 (fast-fast)로 작동한다는 것은 또한 스케치입니다. 이 부작용에 의존하는 대신 목록의 하위 뷰는 수정 횟수를 확인해야합니다. 어쨌든, 나는 왜 그들이 지금 그것에 갇혀 있는지 보게됩니다.

0

소스 코드 java.util.LinkedList (http://developer.classpath.org/doc/java/util/LinkedList-source.html)은 첫 번째 요소와 마지막 요소를 null로 설정할 수 있음을 나타냅니다.

물론 보호하는 경향이 있다면 모든 것을 반복 할 수 있습니다. 나는 당신의 명부가 몇몇 천개의 성분을 보전되는 경우에 이것이 아주 비싼 업무일지도 모른다 개인으로 생각한다.