3

'sock'という名前のソケット変数があり、何らかの理由で新しいソケットを作成する必要がある場合は、'sock2'と呼ばれ、'sock2'を'sock'と等しくなるように設定します。次に、変数「sock」を破棄します。接続は引き続き機能しますか?「sock2」は、元々「sock」にあったソケットのもう一方の端と通信できますか?

4

2 に答える 2

5

sock元々 (の形式で)あったオブジェクトへの参照がまだあるためsock2、Javaガベージコレクションはそれを破棄せず、sock2あたかもそうであるかのように使用できますsock

于 2012-11-16T23:07:37.917 に答える
2

基本的にあなたはこのようなことを説明しています

public void test (...) {
    Socket sock2;
    {
        Socket sock = // open socket
        sock2 = sock;
        // now 'sock' does out of scope; i.e. you "throw it away"
    }

    // use 'sock2'
}

はい、問題なく動作します。sockとは両方ともsock2参照変数です(プリミティブ型ではないJavaのすべての変数も同様です!)。割り当てsock2 = sock;は参照を割り当てるだけです...これで同じものをsock2指すようになり、それを使用して、を介して最初に通信していたリモートホストと通信できます。Socketsocksock


さて、以前にsが異なるsock2ことを指摘した場合はどうでしょうか。 Socket

public void test (...) {
    Socket sock2 = // open socket to A
    {
        Socket sock = // open socket to B
        sock2 = sock;
        // now 'sock' does out of scope; i.e. you "throw it away"
    }

    // use 'sock2'
}

以前と同様に、引き続き機能します。同じ理由で。

これをキャッチするのは、Aに接続されたソケットへの参照を削除したことだけです。ソケットへの参照がなくなった場合A、アプリケーションはそれを使用できません。(これはあなたが話す能力に影響を与えませんB...'あなたはまだその参照を持っています...でsock2)。

では、今何が起こっているのでしょうか?さて、JavaSocketオブジェクトforAがコードで使用できなくなったという状況が発生しました。(Javaの用語では、オブジェクトは「到達不能」です。)これは、ガベージコレクションの対象となることを意味します。ただし、すぐにガベージコレクションされるという意味ではありません。実際、ガベージコレクターが実行されるまでに数秒...または数日...かかる可能性があります。それまでの間、ローカルおよびリモートでリソースを拘束している一部のリモートホストへの接続が開いている可能性があります。これはリソースリークであり、深刻な結果をもたらす可能性があります。(GCが最終的にソケットを再利用すると、実装オブジェクトのファイナライザーは基盤となる接続を閉じ、リソースを解放します。ただし、損傷はすでに発生している可能性があります。)

close()解決策は、コードがタイムリーに作成するオブジェクトを常に確認しSocket、参照が単に「床に落ちる」ことを許可しないようにすることです。

于 2012-11-16T23:44:08.410 に答える