7
1.  public class Tahiti {
2.      Tahiti t;
3.      public static void main(String[] args) {
4.          Tahiti t = new Tahiti();
5.          Tahiti t2 = t.go(t);
6.          t2 = null;
7.          // more code here
8.      }
9.      Tahiti go(Tahiti t) {
10.         Tahiti t1 = new Tahiti(); Tahiti t2 = new Tahiti();
11.         t1.t = t2; t2.t = t1; t.t = t2;
12.         return t1;
13.     }
14. }

7行目に到達すると、ガベージコレクションの対象となるオブジェクトはいくつありますか?

この質問に対する回答によると、11行目にGCの対象となるオブジェクトはありません。しかし、私によれば、6行目でnullを指すように設定されている少なくとも1つのオブジェクトt2は、ガベージコレクションの対象となるはずです。

4

5 に答える 5

8

6 行目の変数 t2 は、オブジェクトへの唯一の参照ではありません。関数 go で作成されたオブジェクト t2 への t からの参照があり、関数 go によって返されたのと同じオブジェクトである t1 への参照を保持します。したがって、6 行目は参照の数を減らすだけですが、オブジェクトへのライブ参照はまだ存在します。

編集: より詳細な説明を試してみましょう。まず、説明を簡単にするためにコードを少し作り直しました。1 行に 1 つのステートメントと混乱の少ない変数名 + 3 つの関連オブジェクトを A、B、C の文字で識別しました。

1.  public class Tahiti {
2.      Tahiti u;
3.      public static void main(String[] args) {
4.          Tahiti t = new Tahiti(); // object A
5.          Tahiti t2 = t.go(t);
6.          t2 = null;
7.          // more code here
8.      }
9.      Tahiti go(Tahiti s) {
10.         Tahiti s1 = new Tahiti(); // object B
11.         Tahiti s2 = new Tahiti(); // object C
12.         s1.u = s2;
13.         s2.u = s1;
14.         s.u = s2;
15.         return s1;
16.     }
17. }

4 行目: 変数 t は、新しいオブジェクトを参照するように初期化されます。そのオブジェクト自体を A と呼びましょう (Java では通常名前はありませんが、この説明のために名前を付けた方が簡単です)。

5 行目: t が関数 go に渡されるので、9 行目に進みます。

9 行目: パラメータ s は、4 行目で作成されたオブジェクト A を参照します。

10 行目: オブジェクト B を指すように変数 s1 を初期化します。

11行目:オブジェクトCを参照するように変数s2を初期化

12 行目: s1.u は s2 を参照するように設定されています。これは、オブジェクト B が C への参照を取得することを意味します。

13 行目: s2.u は s1 を参照するように設定されているため、オブジェクト C は B への参照を取得します。

14 行目: su は s2 を参照するように設定されています。これは、オブジェクト A が C への参照を取得することを意味します。C も B への参照を持っているため、この時点で A から B へのチェーンが存在することに注意してください。

15 行目 オブジェクト B を返し、5 行目に戻る

5 行目: t2 はオブジェクト B を参照するように設定されます (B は、t2 によって直接 1 回、および t が B を参照する C を参照するオブジェクト A を参照するため、2 回参照されるようになりました)

6 行目: 参照 t2 が null に設定されているため、B は 1 つの参照を失いますが、A が参照するポイント C が B を参照する t はまだ有効です

于 2012-12-25T10:32:03.370 に答える
3

次のように、行間をマッピングする表と、行の直後の各オブジェクトを指すアクセス パスのリストを描画するだけです。

╔════════════╦═══════════════════════╦════════════════╦═══════════════════╗
║ After Line ║ Pointers to o1        ║ Pointers to o2 ║ Pointers to o3    ║
╠════════════╬═══════════════════════╬════════════════╬═══════════════════╣
║          3 ║ not allocated         ║ not allocated  ║ not allocated     ║
║          4 ║ main:t                ║ not allocated  ║ not allocated     ║
║          9 ║ main:t, go:this, go:t ║ not allocated  ║ not allocated     ║
║         10 ║ main:t, go:this, go:t ║ go:t1          ║ go:t2             ║
║         11 ║ main:t, go:this, go:t ║ go:t1, o3.t    ║ go:t2, o2.t, o1.t ║
║          5 ║ main:t                ║ main:t2, o3.t  ║ o2.t, o1.t        ║
║          6 ║ main:t                ║ o3.t           ║ o2.t, o1.t        ║
╚════════════╩═══════════════════════╩════════════════╩═══════════════════╝

o1、割り当てられる実際のオブジェクトですo2o3再利用できるオブジェクトの数は、すべての時点で簡単に計算できます。この場合、6 行目以降o1はルートからアクセス可能であり、o3からo1o2アクセス可能o3であるため、オブジェクトを再利用することはできません。

補足として、「しかし、私によれば、少なくとも1つのオブジェクト、t2、...」と書いていることに気付きました。このような問題を解決する必要がある場合は、オブジェクトを指す変数によってオブジェクトに名前を付ける習慣を捨てることをお勧めします。代わりに、上で で行ったように、各オブジェクトに架空の ID を与え、o<n>変数を名前ではなくそれらのオブジェクトへのポインターとして扱います。これは、ポインターと同様に、名前とは異なり、オブジェクトには複数の変数が関連付けられている場合があり、関連付けられている変数のリストは常に変更される可能性があるためです。

于 2012-12-25T11:03:58.350 に答える
2

5行目でメソッドを呼び出しているTahiti.go()ので、プログラムは5行目から10行目にジャンプし、6行目で11に到達します。

于 2012-12-25T10:27:53.200 に答える
1

行番号11は行番号6の前に実行されます

于 2012-12-25T10:27:08.203 に答える
0

ヒープ スタック ダイアグラムは、ガベージ コレクションの対象となるオブジェクトを判断するための最良の方法です。

以下は、上記のコードのヒープ スタック図です。

ヒープ

1000x: TahitiObj: t:2000x

2000x: TahitiObj: 5000x

3000x: TahitiObj: t: 4000x

4000x: TahitiObj: 5000x

5000x: TahitiObj: t: 6000x

6000x: TahitiObj: 3000x

スタック

Main_Stack

args = null

t = 1000x

t2 = null

ただし、実行が完了すると Go_Stack はメモリから削除されます。完全を期すために、ここに保管しました。

Go_Stack

t = 1000x

t1 = 3000x

t2 = 5000x

Main_Stack と HEAP を見ると、直接的または間接的な方法ですべてのオブジェクトにアクセスできることがわかります。

そのため、コード実行が side main メソッドの行番号 7 に達すると、ガベージ コレクションの対象となるオブジェクトはありません。

于 2016-08-06T08:43:53.290 に答える