0

私に与えられ、ガベージコレクションの対象となる時期、つまりどの行であるかを尋ねられた方法。私は両方ともガベージコレクションの資格があると信じていoますoa。以来、それらはに設定されていnullます。私が間違っている場合は、私を修正してください。しかし、問題は、それがいつ、gcどのラインで適格になるかということでした。?

public Object m() {
        Object o = new Float(3.14F);
        Object[] oa = new Object[1];
        oa[0] = o; /* Line 5 */
        o = null; /* Line 6 */
        oa[0] = null; /* Line 7 */
        return o; /* Line 8 */
    }

誰か説明してください。?

4

5 に答える 5

4

コードを見てみましょう。

1)  o = new Float();  
2)  oa = new Object[];  
    at this point we have 2 objects.  
3) oa[0] = o;  
    at this point oa[0] holds the reference of o.  
4)  o = null;  
    o is still being referenced by oa[0]  
5)  oa[0] = null  
    o now has zero references.  
6)  return o;  
     o is null. 

行 7 は、 の GC 適格性が発生する場所ですooa関数が終了するまで、GC の対象にはなりません。

一般に、オブジェクトへの参照が残っていない場合にのみ、オブジェクトは GC の対象となります。StringString プールと呼ばれる特別な場所があるため、a を扱うときは十分に注意してください。したがって、次のコード:

void foo()  
{  
   String s = "foo";   
   s=null;  
   return s;  
}  

s関数で適格であることが保証されているわけではありません。

コメントからの質問

1 つの質問ですが、oa は関数が終了するまで GC の対象になりません。しかし、リターンoの前に、oaはnullに設定され、どこにも参照されていません

答え:

oa が null に設定されていません。null に設定されるのは、oa[0] (oa の最初のインデックス) のオブジェクトです。行が oa = null であった場合、それは true であり、oa 内の唯一の項目が null であるかどうかに関係なく、実際にはラッパー (この場合は配列) を null にしません。List を持ち、そのすべての要素を無効にしても List が null にならないのと同様です。

于 2012-10-31T19:47:48.310 に答える
3

Java は特定の最適化を行うことが許可されているため、ローカル効果のみを理由とする最適化 JIT を使用すると、このコードを次のように単純化できます。

public Object m() {
    //Object o =                    // o does not participate in any externally visible side-effect
    new Float(3.14F);               // Available for collection as soon as ctor finishes.
    //Object[] oa = new Object[1];  // Array ctors are known not to have side-effects, and oa does not participate in a side-effect or result that is visible outside the method.
    //oa[0] = o; /* Line 5 */       // Side-effect not visible.
    // o = null; /* Line 6 */       // Side-effect not visible.
    //oa[0] = null; /* Line 7 */
    //return o; /* Line 8 */        // Eliminated by inlining.
    return null;                    // Type-analysis proves that this method can only return null.
}

nullローカル変数の代入が実際に長期間有効なメソッド呼び出しで行われると想定しないでください。

于 2012-10-31T19:50:59.863 に答える
1

ガベージ コレクションは、そのオブジェクトへの参照が存在しなくなった場合に有効ですが、その時点で GC の実行が保証されないことに注意することが重要な場合があるため、技術的にはメモリを割り当てることができます

oa[0] はオブジェクトを参照しているため、7 行目で null に設定すると、そのオブジェクトへの参照が存在しなくなり、GC の対象となります。

コメントで指摘されているように、配列自体である oa は、メソッドの実行が完了するまで、つまり 8 行目の実行後も存在します。これはメソッド m() の有効期間に対してローカルであるため、m() が実行から戻ったときに GC の対象になります。

于 2012-10-31T19:45:24.893 に答える
0

私が間違っている場合は、私を修正してください。しかし、問題は、それがGCの対象となる時期、つまりどの行であるかということでした。?

質問は無意味であるか、ガベージ コレクションの過度に単純化されたモデルに基づいています。ガベージ コレクターは、実行時に使用可能な表現に基づいて動作します。つまり、レジスタ、スタック、およびグローバル変数を含むグローバル ルートからの到達可能性をトレースします。上位ソースコードとの対応がないので、行番号を聞いても意味がありません。実際には、GC が実行される前に、コンパイラは認識できないほどコードを壊します。

于 2013-01-06T11:16:59.737 に答える
-1

私の知る限り、Java は Mark-And-Sweep アルゴリズムを使用します。GC はヒープ上で別のスレッドで繰り返し実行されます。

特定の参照変数 (またはオブジェクト) が範囲外になると、削除のマークが付けられ、適切な場合 (または上書きされた場合) に一掃されます。

また、変数が null に設定されたとき、つまり参照カウントオブジェクトが静的参照や他のスレッドによって到達不能になったとき、つまりその参照が存在しなくなったときはいつでも、再び削除のマークが付けられます。

コードの 7 行目は、削除対象としてマークされる場所です。

于 2012-10-31T19:46:05.330 に答える