2

ここにいくつかのコードがあります:

public class A {
  private volatile B b;

  public void methodC() {
    b.doSomething();
  }

  public void setB(B newB) {
    this.b = newB;
  }
}

「スレッド1」は、methodC()を実行してb.doSomething()を実行しています。

同時に、「スレッド2」は新しいBオブジェクトを「b」に設定します。

私の質問は:

以前に「b」によって参照されたオブジェクトは、そのオブジェクトのdoSomething()メソッドがまだ実行されているにもかかわらず、ガベージコレクションされる可能性がありますか?

4

2 に答える 2

7

いいえ、メンバー関数を呼び出すには、オブジェクトへの参照が必要なためです。したがって、呼び出しているスレッドはb.doSomething()参照を保持しているため、ガベージコレクションが防止されます。

b可能性がある状況については、以下のJonHarropの回答を確認してくださいGC

于 2012-04-18T13:13:02.907 に答える
1

以前に「b」によって参照されたオブジェクトは、そのオブジェクトのdoSomething()メソッドがまだ実行されているにもかかわらず、ガベージコレクションされる可能性がありますか?

はい、以前に「b」によって参照されたオブジェクトは、そのdoSomething()メソッドがまだ実行されていても、ガベージコレクションされる可能性があります。

メソッドは暗黙的にポインタを渡され、常にスタックにスピルされると想定するthisため、メソッドの1つが実行されている間に到達可能であると期待する場合があります。thisただし、多くの最適化によってこれが変更thisされ、GCによって表示されるグローバルルートのセットから削除される可能性があります。

たとえば、メソッドの本体がdoSomething不要なコードで終わりthis、メソッドがインライン化thisされている場合、レジスタからスタックにスピルされないか、スタックスロットが上書きされる可能性があります。いずれの場合thisも、実行がまだ内部doSomethingにある場合でもGCは認識しなくなるため、thisガベージコレクションが行われる可能性があります。

于 2013-07-11T22:19:43.320 に答える