11

これは本当にばかげた質問だと思いますが、次のようになります。

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は、それを示唆しています。

ティア...

4

4 に答える 4

19

彼らの方法は、他のコードがまだ特定のノードへの参照を保持している場合でも、他のノードが GC されることを保証します。

そうしないと、ノードの 1 つに対する外部参照が 1 つでもあるだけで、チェーン全体が収集されなくなります。

また、リスト内の他の操作が同時に行われている可能性があります (たとえば、subList()またはCollections.unmodifiableList()、イテレータを介したビュー)。これにより、これらの操作がリストを「空」として即座に認識することが保証されます。

于 2009-02-22T22:48:36.817 に答える
2

IIRC、これは特定の(世代の)GCアルゴリズムのパフォーマンスを支援するためにJDK6で行われた変更でした。多くの場合、Listそれ自体と古いノードは、他のいくつかのノードよりも古い世代になります。若い世代はより頻繁に収集されるため、すべてのノードがガベージであることが検出される前に、若いノードがコピーされます。

したがって、これはマイナーなパフォーマンスの最適化です。メモリパフォーマンスの最適化は、実行に追加の時間がかかる問題を引き起こしているのはコードではないことが多いという点で少し奇妙です。

于 2009-02-23T12:43:20.117 に答える
0

私はゲーム開発ブログでまさにこの問題について推測していました。答えてくれてありがとう。ノードの露出は疑わしい設計上の許容範囲であると私は主張します。また、リストの代替ビュー (反復子など) がノードのリンク解除に依存してフェイルファストになることも大ざっぱです。この副作用の動作に依存する代わりに、リストのサブビューは変更数をチェックする必要があります。いずれにせよ、なぜ彼らが今それで立ち往生しているかがわかります。

于 2009-05-29T17:50:45.243 に答える