4

[始める前に、関連する質問を検索してみましたが、何も見つからなかったので、ここで質問します]

私はJavaを学んでおり、次のシナリオが頭に浮かびます。

class MyThread extends Thread {
    void run(){
        //a heavy function
    }
}

そして今、メインスレッドで、このスレッドを次のように呼び出します。

public static void main(...){
    new MyThread().start();
    System.gc(); //just a request..
    //end of main thread too.
    //Reference to that MyThread object is now zero.
}

そのコードを実行しました。スレッドはまだ生きているようです。すべてのスレッドが終了すると、プログラムは終了します。

私の質問:

  • 参照カウントがゼロの場合、スレッドはGCの対象になりませんか?それが本当に適格である場合、ガベージコレクションの動作はどうなりますか?スレッドは終了しますか?
  • 私はそれが悪いことであることを知っていますが、それがないことは明確に定義されていotherThread.join()ますmain()か?

私は自分自身についていくつか説明しています(しかし、私がどれほど正しいかはわかりません-ここに投稿した理由):

  • JVMは、アクティブである限り、スレッドへの参照を維持します。したがって、参照カウントが実際にゼロになることはありません。
  • 実行中の関数には暗黙thisの参照があるため、参照カウントもゼロではありません。

上記の説明のいずれかで正しいですか?それとも他に何か説明はありますか?

ありがとう、よろしく:)

4

3 に答える 3

13

実行中の各スレッドは、GCのルートを構成します。ルートの1つから到達可能なオブジェクトは、GCの対象ではなく、スレッドにはjava.lang.Threadインスタンスへのスレッドローカル参照があります(によって返されますThread.currentThread())。いいえ、実行中Threadのスレッドからインスタンスに到達できるため、実行が終了するまでスレッドはGCされません。

join()スポーンされたスレッドを呼び出さないことがなぜ悪いことになるのかわかりません。生成されたスレッドがいつ終了するかを気にしない場合は、スレッドに参加する必要はありません。最後の非デーモンスレッドの実行が停止すると、アプリケーションは停止します。

また、参照の数は、オブジェクトがGCに適格であるかどうかを判断するためにGCが使用する数ではないことに注意してください。相互の参照を維持するオブジェクトのグラフ(たとえば、DOMツリー)は、グラフに到達できなくなった場合にGCの対象となる可能性があります。

于 2012-07-16T07:26:05.613 に答える
4

1. JVM will terminate only when all the Non-Daemon thread including the Main thread終了しました。(main()メソッドではなくメインスレッド)。

2.スレッドは、run()メソッドの実行が終了するとすぐに終了しますが、ご存知のとおり、すべてのスレッド(つま先、つまり実行スレッド)はThreadクラスのインスタンスに関連付けられています。

3.したがって、スレッドが停止すると、デッド状態に移行します(ここではスレッドプールについては言及していません)が、スレッドに関連付けられていたThreadクラスのオブジェクトはまだ存在しますが、スレッド性は永久に失われています。

4.ただし、スレッドがまだ実行されている可能性が高く、mainメソッドのみが終了しています。

5.呼び出しjoin()はまったく悪いことではありませんが、注意して使用する必要があります。

于 2012-07-16T07:29:05.953 に答える
2

参照カウントがゼロの場合、スレッドはGCの対象になりませんか?

いいえ。スレッドが終了し、参照がない場合、スレッドはGCの対象になります。

それが本当に適格である場合、ガベージコレクションの動作はどうなりますか?スレッドは終了しますか?

上記を参照。

私はそれが悪いことであることを知っていますが、main()にotherThread.join()がないように明確に定義されていますか?

これは悪いことではなく、完全に明確に定義されています。デーモン以外のすべてのスレッドが終了すると、JVMは終了します。

JVMは、アクティブである限り、スレッドへの参照を維持します。したがって、参照カウントが実際にゼロになることはありません。

正しい。

実行中の関数には暗黙のこの参照があるため、参照カウントもゼロではありません。

正しくない。静的メソッドを検討してください。実行中の関数は、定義上、アクティブなスレッドで実行されているため、定義上、スレッドはアクティブであるため、GCすることはできません。ここでのあなたの考えはかなり循環的です。

于 2012-07-16T10:50:00.697 に答える