2

メモリを占有するリスト型のオブジェクトがガベージ コレクションの対象になるのはいつですか。また、リストへの参照を保持する変数はどこにありますか。以下のコードの場合、変数は割り当てられていません。

ケース 1:

for (Integer i : returnList()) { 
    System.out.println(i);
}

次のようなコードの場合:

ケース 2:

List list = returnList();
for (Integer i : list) { 
    System.out.println(i);
}
   list = null;

GC を制御できます。変数が割り当てられていない最初のケースでそれを処理する方法はありますか?

要約する:

  1. リストへの参照変数がないケース1の場合、参照のメカニズムは何ですか?

  2. スタック フレームがポップされると、リストは GC の対象になりますか?

  3. GC'ing の適格性を早める方法はありますか?

4

4 に答える 4

3

リストへの参照変数がないケース1の場合、参照のメカニズムは何ですか?

リストへの暗黙の参照があります。forこれは、強化されたものを次のように翻訳することで理解できます。

for(Iterator e = returnList().iterator(); e.hasNext(); ) {
    Integer i = (Integer)e.Next();
    System.out.println(i);
}

ここで、eは のイテレータへの参照を持ちreturnList、それ自体は への参照を持ちますreturnList。したがって、制御がループ内にある間のみ真になる is rooted であるreturnList限り、 is rooted です。コントロールが本体を離れると、コレクションの対象になるため、コレクションの対象になります。eforforereturnList

もちろん、これはすべて、

  1. の所有者はreturnList、その戻り値への参照を維持していません。
  2. 同じリストが別の呼び出し元に返されておらず、その別呼び出し元が同じリストへの参照を維持していません。

スタック フレームがポップされると、リストは GC されますか?

必ずしも。リファレントにルート化された参照がないことを JVM が判断できる場合、コレクションの対象となります。必ずしもすぐに収集されるわけではないことに注意してください。

ケース1でGCを高速化する方法。

forコントロールがループを離れるよりも早く収集することはできません。制御がループを離れた後に収集される場合がありますforJVMにこれを心配させてください。

手動でガベージ コレクションを試みることができることに注意してください。

System.gc();

ただし、これによりガベージ コレクションがトリガーされると、完全なガベージ コレクションになる可能性があるため、動作が悪化する可能性があることに注意してください。JVM はこの要求を無視できることに注意してください。ここで多くの CPU サイクルを浪費している可能性があります。メモリが無限のシステムでは、ガベージ コレクタを実行する必要がないことに注意してください。このようなシステムでは、ガベージ コレクターが要求に従う場合、ガベージ コレクターを要求すると、CPU サイクルが完全に無駄になる可能性があります。

JVM にガベージ コレクションを管理させます。そのためのアルゴリズムは高度に調整されています。

于 2013-08-12T19:52:00.300 に答える
0

GC を制御することはできません。GC は JVM によって管理されます。管理できるのは、どのオブジェクトをガベージ コレクションに使用できるかです。ただし、ファイナライズ メソッドを使用してガベージ コレクターがいつ実行されるかを確認できます。オブジェクトが削除される前に常に呼び出されます

public class Demo{    

   static  void create()
     {
         Demo o = new Demo();
     }
     public void finalize()
       {
          System.out.println("GC called");
       }

    public static void main (String ...ar)
     {

       for (long  i=1;i<900000;i++)  //Try changing values here
            {
               create();
            }
    }
}

メソッド内で作成されたオブジェクトは、メソッドが返されたときに GC で使用できます (メソッドの実行中にローカル変数が存在するように)。ただし、メソッドがオブジェクトを返す場合、ガベージ コレクションには使用できません。

public class Demo{    

   public void getDate()
     {
        Date o = new Date();
        StringBuffer d = new StringBuffer(o.toString());
        System.out.println(d);
        return o;
     }
    public static void main (String ...ar)
     {
            Date x= getDate();
    }
}

上記のコードでは、オブジェクト d は、メソッドが返されたときに GC で使用できます。ただし、オブジェクト o はコレクションに使用できません

于 2013-08-12T20:30:54.923 に答える
0

SCJP 256-257ページより

ガベージ コレクターは魔法のような未知の操作を行い、どのライブ スレッドからもアクセスできないオブジェクトを検出すると、そのオブジェクトを削除の対象と見なし、ある時点で削除することさえあります。オブジェクトに到達することについて話すとき、実際には、問題のオブジェクトを参照する到達可能な参照変数を持つことについて話しています。Java プログラムにオブジェクトを参照する参照変数があり、その参照変数がライブ スレッドで使用できる場合、そのオブジェクトは到達可能と見なされます。

オブジェクトを NULL に設定すると、GC がオブジェクトを削除するときに固定するのに役立つ場合がありますが、そうでない場合もあります。それを制御することはできません。JVM はメモリが不足していることを感知すると GC を実行し、手動で実行するように要求できますが、何も保証されません。

于 2013-08-12T19:51:51.833 に答える
0

リストへの参照変数がない場合の参照のメカニズムは何ですか?

次の回答を参照してください。

スタック フレームがポップされると、リストは GC されますか?

リストはヒープ上に作成されますが、それへの唯一の参照がスタック上にある場合は、GC によって収集される資格があります。とはいえ、それがすぐに実現するというわけではありません。

ケース1でGCを高速化する方法。

System.gc();GC がその作業を実行できることを「示唆」しているだけであると呼んでも、GC を「高速化」することはできません。

その背後にも多くの意味があります。たとえば、プログラムが使用するメモリが 2GB あり、現在は 2KB しか使用していないとします。一部のオブジェクトが削除の対象となるという理由だけで、GC がプログラムの実行を停止し、メモリをクリーンアップすることを正当化するものではありません。

于 2013-08-12T19:52:03.807 に答える