4
class Beta { }

class Alpha {
static Beta b1  ;
Beta b2;
}

public class Tester {

public static void main(String[] args) {

    Beta b1 = new Beta();
    Beta b2 = new Beta();
    Alpha a1 = new Alpha();
    Alpha a2 = new Alpha();

    a1.b1 = b1 ;
    a1.b2 = b1 ;
    a2.b2 = b2 ;

    a1 = null ;
    b1 = null;
    b2 = null;

    System.out.println(" Line 1    " + " a1   "  + a1.b1);
    System.out.println(" Line 2    " + " a1   "  + a1.b2);
    System.out.println(" Line 3    " + " a2   " + a2.b2);
    System.out.println(" Line 4    " + " a1   " + a2.b1);
    System.out.println(" Line 5    " + " b1   " + b1);
    System.out.println(" Line 6    " + " b1   " + b2);

  }

 }  

上記のプログラムでガベージ コレクションに a1 オブジェクトしか使用できない理由がわかりません。a1 、 b1 、および b2 がガベージコレクターによって収集されることを期待しています。

ご覧のとおり、 a1 、 b1 、および b2 は NULL になっているため、オブジェクトをガベージ コレクションで使用できるようになっています。オブジェクトが NULL であるか、どのスレッドまたは参照変数からも到達できない場合、ガベージ コレクターによって収集する必要があります。

誰かが上記のプログラムの微妙さを良い例でより正確に理解するのを手伝ってくれますか? あなたの助けに感謝します。

4

5 に答える 5

8

以下の行により、b1 & b2 refrences が指すオブジェクトへの参照がまだ存在するためです。

a1.b1 = b1 ;
a1.b2 = b1 ;
a2.b2 = b2 ;

次のように仮定します。

  b1--->BetaObj1
    b2---BetaObj2
    a1---> AlphaObj1
    a2---> AlphaObj2

a1.b1 は b1 を指します。これは、BetaObj1 への参照があることを意味します。a1.b2 は、BetaObj1 への別の参照があることを意味する b1 を指します。

(この時点で BetaObj1 への参照が 3 つあります)

a2.b2 は b2 を指しています。つまり、BetaOBj2 への参照があります。

(この時点で、BetaObj2 への参照が 2 つあります)

a1=null;AlphaObj1 を GC の対象にします

b1=null;BetaObj1 の参照カウントを 2 にするため、このオブジェクトは GC の対象外です

b2=null;BetaObj2 参照カウントを 1 にするため、このオブジェクトは GC の対象になりません。

于 2012-08-01T14:15:11.457 に答える
1

ここで取得する必要がありNullPointerExceptionます:

System.out.println(" Line 1    " + " a1   "  + a1.b1);
System.out.println(" Line 2    " + " a1   "  + a1.b2);

その時点で、a1はすでに に設定されているため、オブジェクトを参照していないためnull、そのメンバーへのアクセスは機能しません。(インスタンスではなくクラスのみが必要なためb2、静的な作品へのアクセスは機能します。)b1

ご覧のとおり、 a1 、 b1 、および b2 は NULL になっているため、オブジェクトをガベージ コレクションで使用できるようになっています。

いいえ、これらのオブジェクトへのいくつかの参照を に設定しましたが、 および の場合のように、これらのオブジェクトへのnull他の参照が存在します。これらのオブジェクトはまだ収集できません。b1b2

于 2012-08-01T14:18:49.120 に答える
1

ここにはいくつかの誤解があります

  • GC は必要なときにのみ実行されます。GC を必要以上に頻繁に実行することは、必要のない作業を行うことになります。
  • a1.b1実際にはインスタンスは重要ではなく、使用Alpha.b1することさえできるので、紛らわしいです。nullal.b1
  • a1.b2a1 が であるため、 NullPointerException をスローする必要がありnullます。
  • Alpha.b1は設定されていますが、どこにもクリアされていないため、参照されているオブジェクトはクリーンアップの対象ではありません。他のオブジェクトをクリーンアップすることはできますが、明示的に呼び出さSystem.gc();なければ、予期した時点で実行する必要がある可能性はほとんどありません。
  • a1クリアされますがa2、そうではないため、クリーンアップされません (メソッドが戻るまで)
于 2012-08-01T14:43:58.360 に答える
1
  • b2a2.b2まだ参照があるため、gc では使用できません
  • b1Alpha.b1gcへの参照を保持しているため、 gc では使用できません(Alpha.b1静的です。 を使用して設定されているため、混乱しないでくださいa1.b1) 。
于 2012-08-01T14:17:09.893 に答える