静的フィールドはガベージコレクションのために開いていますか?


95

プログラムのセットアップでのみ使用される架空のユーティリティクラスがあるとします。

class MyUtils {
   private static MyObject myObject = new MyObject();
   /*package*/static boolean doStuff(Params... params) {
       // do stuff with myObject and params...
   }
}

myObjectは、使用されなくなったときにガベージコレクションされますか、それともプログラムの存続期間中存続しますか?

回答:


112

クラスがロードされている間、静的変数をガベージコレクション用に選択することはできません。それらは、(このクラスのロードを担当した)それぞれのクラスローダー自体がガベージのために収集されるときに収集できます。

JLSセクション12.7のクラスとインターフェースのアンロードを確認してください。

定義されたクラスローダーがガベージコレクターによって再利用される場合に限り、クラスまたはインターフェースがアンロードされる可能性があります[...]ブートストラップローダーによってロードされたクラスおよびインターフェースがアンロードされない場合があります。


@bruno、リンクごとに、ロードされたクラスに静的メンバーがない場合でも、クラスローダーがロードするすべてのクラスへの参照を保持することを意味しますか?
Pacerier 2014

@brunoconde、私はそれが本当だとは思いません。正確にどの段落がそれを述べていますか?(stackoverflow.com/questions/405364/…のディスカッションを続けてください)
Pacerier 2014

クラスローダーがガベージコレクションの対象となる場合。?
Rohit Bandil 16

@RohitBandil-到達できない場合。
スティーブンC

55

静的変数は、ClassLoadersによって参照されるClassオブジェクトによって参照されます。つまり、ClassLoaderが何らかの方法でクラスを削除した場合(それが可能な場合)、またはClassLoader自体がコレクションに適格になった場合(Webアプリケーションのアンロードを考えると)、静的変数(またはむしろ、それらが参照するオブジェクト)は収集されません。


1
でくださいClass何の静的変数が含まれていないオブジェクトは、クラスローダによって参照されますか?
Pacerier 2014

14

一時的なオブジェクトを静的な初期化に使用して破棄したい場合は、静的な初期化ブロックを使用できます。

class MyUtils {
   static
   {
      MyObject myObject = new MyObject();
      doStuff(myObject, params);
   }

   static boolean doStuff(MyObject myObject, Params... params) {
       // do stuff with myObject and params...
   }
}

静的初期化ブロックは特別な種類の静的メソッドであるため、myObjectはローカル変数であり、ブロックの実行終了後にガベージコレクションを実行できます。


13

myObjectは参照であり、オブジェクトではありません。オブジェクトは到達不能であるため、参照が指し示していない場合、オブジェクトは自動的にガベージコレクションされます。

したがって、静的参照「myObject」の背後にあるオブジェクトも、次のように逆参照するとガベージコレクションされる可能性があります。

myObject = null;

このオブジェクトへの他の参照はありません。

ただし、静的参照と変数はプログラムの存続期間中残ります。


StackOverflowへようこそ!nullの最後にオブジェクトを設定することstatic blockは、実行可能なオプションです。しかし、私の場合、オブジェクトの有効期間は静的ブロックよりも長くする必要がありました。オブジェクトの有用性の終わりはあまり具体的ではありませんでした。したがって、ガベージコレクタの利用について私の質問。
Michael Deardeuff 14

7

私はこれがあなたの質問に答えると思います-基本的に、クラスが特別なクラスローダーから来て、それがクラスをアンロードしない限り、そうではありません。


0

ここで重要なのは、クラスインスタンス、つまりオブジェクトのガベージコレクションです。ClassLoaderインスタンスは、本質的にはオブジェクトです。したがって、Classloaderオブジェクトがガベージコレクションされていない場合、ヒープに格納されているそれらの参照(つまり、静的なもの)がガベージコレクションされることはほとんどありません。例外は文字列プールです。

それで、あなたが突然private static MyGiantClass myGiantObject = new MyGiantClass() 、私が難しい方法を学んだので、考えることを二度考えることを決める前に 。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.