多分少し遅れているかもしれませんが、現在の説明は私にとっては完全に不満であり、私はもっと賢明な説明をしていると思います。
まず、すべてのJava GCは、ルートセットから何らかの種類のトレースを行います。つまり、古いヘッドが収集された場合は、next
変数を読み取ることはありません。その理由は何もありません。したがって、IF頭は次の反復で収集されても問題はありません。
ここで、上記のIFが重要な部分です。異なる設定の次の設定の違いは、ヘッド自体の収集には関係ありませんが、他のオブジェクトには違いが生じる場合があります。
単純な世代GCを仮定しましょう。ヘッドが若いセットにある場合、それは次のGCで収集されます。しかし、それが古いセットに含まれている場合、まれに起こる完全なGCを実行したときにのみ収集されます。
ヘッドが古いセットにあり、若いGCを実行するとどうなりますか?この場合、JVMは古いヒープ内のすべてのオブジェクトがまだ生存しているとみなし、古いオブジェクトから若いオブジェクトのすべての参照を若いGCのルートセットに追加します。これは、割り当てがここで避けていることです:古いヒープへの書き込みは、一般的に、JVMがそのような割り当てをキャッチして正しく処理できるように、書き込みバリアなどで保護されます。この場合、ルートセットからオブジェクトnext
が削除されますそれは結果をもたらす。
ショート例:
は、私たちが1 (old) -> 2 (young) -> 3 (xx)
を持っていると仮定します。リストから1と2を削除すると、両方の要素が次のGCによって収集されることが予想されます。しかし若いGCのみが発生し、古いもののnext
ポインタを削除していない場合、要素1と2は両方とも収集されません。これに反して、我々は1で、ポインタを削除した場合、2は若いGCによって収集されます。..
出典
2012-01-14 03:44:13
Voo
多分コメントが古いされます(バージョン管理を見つけて、コミットにコメントを追跡することができますか?):) – milan
それは、この一時varとコメントのみで追加されたことは興味深いですそれで、それは確かにいくつかの意図によって行われました。 http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/LinkedBlockingQueue.java#LinkedBlockingQueue.extract%28%29およびhttp: /grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/concurrent/LinkedBlockingQueue.java#LinkedBlockingQueue.dequeue%28%29 – Vadzim
これは、openjdk、OracleのLinkedBlockingQueueです。 Mac(1.6.0_29-b11-402.jdk)のjdk 6には一時変数があります。 – milan