线程的垃圾收集线程、垃圾

2023-09-03 16:30:19 作者:26.以后、拿命爱自己

我是否需要保护从垃圾收集器的对象?怎么样,它包含了线程运行的功能?对象

Do I need to protect Thread objects from the Garbage Collector? What about the object that contains the function that the thread runs?

考虑一个简单的服务器:

Consider this simple server:

class Server{
    readonly TcpClient client;

    public Server(TcpClient client){this.client = client;}

    public void Serve(){
        var stream = client.GetStream();
        var writer = new StreamWriter(stream);
        var reader = new StreamReader(stream);

        writer.AutoFlush = true;
        writer.WriteLine("Hello");

        while(true){
            var input = reader.ReadLine();
            if(input.Trim() == "Goodbye")
                break;
            writer.WriteLine(input.ToUpper());
        }

        client.Close();
    }
}
static void Main(string[] args){
    var listener = new TcpListener(IPAddress.Any, int.Parse(args[0]));
    listener.Start();

    while(true){
        var client = listener.AcceptTcpClient();
        var server = new Server(client);
        var thread = new Thread(server.Serve);
        thread.Start();
    }
}

我应该换我的线程对象的某种静态的集合,以防止它们被横扫了由垃圾收集器?

Should I wrap my thread objects in some sort of static collection to keep them from being swept up by the garbage collector?

presumably,如果对象本身保持活着,那么服务器对象将活下去,因为线程持有参考到保存的参考目标对象的委托。或者,也许线程对象本身的收集,但实际的线程继续运行。现在服务器的对象是注册收藏。然后呢,如果它试图访问其字段(S)会发生什么?

Presumably, if the Thread object itself stays alive, then the Server object will live, because the thread holds a reference to the delegate which holds a reference to the target object. Or maybe the thread object itself is collected, but the actual thread continues to run. Now the Server object is up for collection. And then what happens if it tries to access its field(s)?

垃圾收集让我目瞪口呆了一些时间。我很高兴我通常不会去想它。

Garbage collection makes my head spin some times. I'm glad I usually don't have to think about it.

考虑到潜在的陷阱在这里,我愿意相信,垃圾收集器是足够聪明不征收线程对象时,线程本身仍在执行,但我找不到任何文档这样说。反射器是没有什么帮助在这里,因为许多发的类,勿庸置疑,实施 MethodImplOptions.InternalCall 功能。我宁愿不通过SSCLI我的老过时的副本的答案(一方面是因为这是一个痛苦,因为它不是一个肯定的答案)。

Given the potential gotchas here, I would like to believe that the garbage collector is smart enough not to collect thread objects when the thread itself is still executing, but I can't find any documentation saying so. Reflector is of little help here, since much of the Thread class is, unsurprisingly, implemented in MethodImplOptions.InternalCall functions. And I'd rather not dig through my old outdated copy of SSCLI for answers (both because it's a pain, and because it's not a sure answer).

推荐答案

这是很简单的。真正的执行线程不线程对象。该计划正在执行中生存,无论你的.NET垃圾回收器与您的Thread对象真正的Windows线程。因此它是安全的你;你不需要关心Thread对象,如果你只是希望程序继续运行。

It is quite simple. The real execution thread is not Thread object. The program is executing in real Windows threads which stay alive regardless of what your .NET garbage collector does with your Thread objects. So it is safe for you; you don't need to care about Thread objects if you just want the program to keep running.

另外请注意,你的线程不要让他们跑的时候收集的,因为它们实际上属于应用程序的根。 (罗茨 - 这是如何的垃圾收集器知道什么是活着的)

Also note that your threads don't get collected when they run, because they in fact belong to the application "roots". (Roots - it's how garbage collector knows what is alive.)

详细信息:的托管线程对象通过 Thread.CurrentThread 访问 - 这有点像一个全局静态变量,这些不得到收集。正如我前面写的:任何托管线程这是开始,现在执行任何code(连外.NET的),不会失去它的Thread对象,因为它是牢固地连接到根

More details: A managed Thread object is accessible via Thread.CurrentThread - that is something like a global static variable and those don't get collected. As I wrote earlier: Any managed thread which was started and now executing any code (even outside of .NET), doesn't lose its Thread object, because it is firmly connected to "roots".