私の記憶が正しければ、Javaで1を書くことができます
new JFrame();
保存せずにJFrame
任意の変数の参照を。このプログラムは、画面上のGUIウィンドウを表示し、プログラムが閉じられるまで、開いたままにしておきます。(この前提が偽であるなら、私を修正してください)。
理論的には、我々は、以来ことを考えることができJFrame
GCは、いくつかの点でオブジェクトを解放する必要があり、今でユーザーコードから到達不能です。そしてその結果として、関連するOSのリソース(GUI画面など)がうまくとして解放されます。
しかし、私の理解が正しければ、 - そのプログラムは、(かなり役に立たない1が)有効な作業のJavaプログラムであり、(この前提が間違っている場合は、再度正しい私に)それがどの時点で奇妙な方法でクラッシュしたり、動作しません。
GCが収集することはありませんようだJFrame
が、それへの参照がないか、にも関わらず、オブジェクトが、少なくともそれは、関連するOSのリソースが解放されることはありません。
これが可能である方法:私は理解したいと思いますか?
コンストラクタい
JFrame
セーブでthis
任意の場所には、収集されないようにするためには?ソースコードJFrame
のスーパーするjava.awt.Frame(方法noteFrame
)フレームは、弱参照キューに保存されているように見えます。しかし、これらは弱参照なので、それは物事を説明していないようですそれは、GCがある場合、実際にあるん最終的に解放
JFrame
しかし、のファイナライザ方法は-JFrame
しない GUIウィンドウの滞在が開くので、関連するOSのリソースを解放するには?その他の説明は?
これは、より多くの質問へのフォローアップであることをしてください、ノート、私はSE.SEに掲載理論的な質問。それはJava実装の詳細に特異的に関係するので、この質問は異なっています。
A JFrame
のみを介して作成されたnew JFrame()
任意の追加のアクションなしには、画面上で開かれていませおよびガベージコレクションを防止しません。表示装置に接続されている唯一のフレームは、AWTの実装から参照され、それが明示的に切断されている前に、ガベージコレクションを取得することはできません。
これは次のコードで確認できます。
public static void main(String[] args) {
check(new JFrame(), "just creating a JFrame", x -> {});
check(new JFrame(), "creating and connecting a JFrame", JFrame::pack);
check(Frame.getFrames()[0], "calling dispose()", Frame::dispose);
}
private static <T> void check(T obj, String description, Consumer<T> action) {
System.out.println(description);
action.accept(obj);
WeakReference<T> r = new WeakReference<>(obj);
obj = null;
System.gc();
if(r.get() == null) System.out.println("collected immediately");
else {
System.runFinalization();
System.gc();
if(r.get() == null) System.out.println("collected after finalization");
else System.out.println("still alive");
}
}
これは印刷されます
just creating a JFrame
collected immediately
creating and connecting a JFrame
still alive
calling dispose()
collected after finalization
一般的な実装インチ
接続されて以降、上の切断を経由してフレームのに対し、表示装置に接続されることはなかったフレームは、すぐに通常のオブジェクトと同じように収集されることを注意することの価値dispose()
通話が最初のガベージコレクタの実行後に行われるクリーンアップのアクションを必要とし、 。
さらに、この例では使用しpack()
なくsetVisible(true)
フレームが表示されることなく表示装置に接続され得ることができることを実証します。これは、の差になりisDisplayable()
成分がスクリーン装置とに接続されているかどうかを反映しisVisible()
ているかどうかを指示可視プロパティがに設定されているがtrue
。最後に、コンポーネントのみを報告しないisShowing()
ようtrue
には見えると表示されたときに、その親のすべてが表示されます。