java - 当套接字被取消引用时,它们是否被垃圾收集

标签 java multithreading sockets networking garbage-collection

我正在尝试理解 SO_TIMEOUT、线程资源和垃圾收集的概念。

我在我的项目中发现了一个编码错误,其中一组套接字在没有关闭的情况下被错误地取消引用。

在 JAVA 1.6 中,它们会在几分钟内关闭,但在 JAVA 1.8 中,它们需要数小时才能关闭。 [仅在linux平台上测试]

所以我想更深入地研究这个问题。

我创建了这个程序,我在其中创建了 10 个套接字,但正如您所看到的,其中 9 个被取消引用,然后线程进入长时间 hibernate :

    import java.net.Socket;

/**
 * Created by 212477559 on 5/30/16.
 */
public class TestClientSocket {

    public static void main(String args[])
    {
        try
        {
            Socket socket;
            for(int j=0;j<10;j++)
            {
                socket =new Socket("localhost",9090);
                socket.setKeepAlive(false);
            }


            Thread.sleep(900000);

        }
       catch(Exception e)
        {
            System.out.println("throws");
            e.printStackTrace();
        }
    }
}

现在当我运行的时候

netstat -np TCP | find "9090"

半小时左右后,我仍然可以看到所有套接字仍处于已建立状态。所以我有以下问题:

1) 为什么这 9 个套接字没有被垃圾回收?

2) 该线程是否仍持有资源?

3)是下面提到的关闭套接字的唯一方法:

   1. close the sockets?
   2. Thread which created those sockets must exit?
   3. SO_TIMEOUT should expire?

最佳答案

垃圾收集与这些 Sockets 仍然打开的事实无关。

简单介绍一下:

Garbage collection is the process of looking at heap memory, identifying which objects are in use and which are not, and deleting the unused objects. An in use object, or a referenced object, means that some part of your program still maintains a pointer to that object. An unused object, or unreferenced object, is no longer referenced by any part of your program. So the memory used by an unreferenced object can be reclaimed.

现在,虽然 Socket 对象使用的内存可能会被回收,但这并不意味着操作系统对 Socket 的句柄会随着 JVM 回收内存的过程而被销毁(这是两个独立的事情) .

这就是为什么 close为套接字提供了方法。这是保证操作系统释放套接字句柄的唯一方法。

套接字在不再需要时应始终关闭。

And they get closed within few minutes with JAVA 1.6 but with JAVA 1.8 they take hours to close.

如果他们关闭了,这甚至不应该成为讨论点。

关于java - 当套接字被取消引用时,它们是否被垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37576330/

相关文章:

java - 仅带有 websocket 客户端的 Spring Boot 应用程序

java - 第二次排序更快

java - 构建器模式代替方法重载

c# - 停止dll循环

Linux 套接字传输正在添加额外的零填充

java - Zxing上编译错误

java - Java 服务器中每个游戏室的线程?

C# 垃圾收集器、线程和编译器/抖动优化

c - Tcp 服务器关闭卡在 TIME_WAIT,无法再次在同一端口上打开服务器

java - 在 Android 中配对(绑定(bind))后如何以编程方式连接到蓝牙设备