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现在指向相同Socket的,sock您可以使用它与您最初通过 交谈的远程主机交谈sock


好的,那么sock2之前指向 s different 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... 交谈的能力,因为您仍然有那个参考 ... in sock2)。

那么现在会发生什么?好吧,我们现在遇到了 JavaSocket对象A不再可供代码使用的情况。(用 Java 的说法,对象是“不可访问的”。)这意味着它有资格进行垃圾回收。但这并不意味着它会立即被垃圾收集。事实上,垃圾收集器运行之前可能需要几秒钟……或几天……。同时,可能仍然存在与某些远程主机的开放连接,从而在本地和远程绑定资源。这是资源泄漏,可能会造成严重后果。(当 GC 最终回收套接字时,实现对象的终结器将关闭底层连接并释放任何资源。但损坏可能已经造成。)

解决方案是确保您的代码始终及时创建close()任何Socket对象......并且不允许引用只是“掉在地板上”。

于 2012-11-16T23:44:08.410 回答