C# 具有长时间运行线程的垃圾收集对象

C# 具有长时间运行线程的垃圾收集对象,c#,garbage-collection,C#,Garbage Collection,如果有一个对象具有无限循环,它是否会被垃圾收集(当线程运行时) 我做了一个程序来测试这一点,它似乎永远不会被垃圾收集,但我希望有更多的经验来证实这一点 编辑:我忘了添加示例。这是我用过的例子 class Program { static void Main(string[] args) { WeakReference wr1 = InitializeClassWithLoop(); WeakReference wr2 = InitializeCla

如果有一个对象具有无限循环,它是否会被垃圾收集(当线程运行时)

我做了一个程序来测试这一点,它似乎永远不会被垃圾收集,但我希望有更多的经验来证实这一点

编辑:我忘了添加示例。这是我用过的例子

class Program
{
    static void Main(string[] args)
    {
        WeakReference wr1 = InitializeClassWithLoop();
        WeakReference wr2 = InitializeClassWithoutLoop();

        GC.Collect(2);
        GC.Collect(2);
        GC.Collect(2);
        GC.WaitForPendingFinalizers();

        Thread.Sleep(30000);
        Console.WriteLine($"ClassWithLoop.IsAlive = {wr1.IsAlive}\nClassWithoutLoop.IsAlive = {wr2.IsAlive}\n");
        Console.ReadLine();
    }

    static WeakReference InitializeClassWithLoop()
    {
        var cs = new ClassWithLoop();
        return new WeakReference(cs);
    }

    static WeakReference InitializeClassWithoutLoop()
    {
        var cs = new ClassWithoutLoop();
        return new WeakReference(cs);
    }
}

public class ClassWithLoop
{
    public ClassWithLoop()
    {
        Thread thread = new Thread(Loop);
        thread.Start();
    }

    private void Loop()
    {
        int counter = 0;
        while (true)
        {
            counter++;
            Thread.Sleep(1000);
        }
    }
}

public class ClassWithoutLoop
{
    int counter;

    public ClassWithoutLoop()
    {
        counter = 5;
    }
}
结果是:
ClassWithLoop.IsAlive=True

ClassWithoutLoop.IsAlive=False

我只能假设您的意思是一个类中有一个无限循环的方法:

public class A
{
  public void IDontEverEnd()
  {
    while(true) { }
  }
}
假设你做了这样的事情:

Task.Factory.StartNew(() => {
  new A().IDontEverEnd();
})
然后您的程序将保持活动状态,因为它将只在单独的线程上运行,但不会被垃圾收集;这是因为对
idontverend
的调用从未退出,因此对
A
实例的引用从未停止使用


编辑 正如mjwills在评论中提到的那样,即使正在对某个项执行方法,有时也有可能对其进行垃圾收集


尽管在实践中,只要你不处理p/invoke之类的东西,很可能这对你来说并不重要。

你是说无限循环中使用的对象?你是在每个循环中使用相同的对象还是创建新的对象?什么是“带循环的对象”?只要进程(无论哪个线程)引用了某个对象,就永远不会对该对象进行垃圾收集。请提供一些代码来说明您的问题。@PowerStar,例如,如果您有行
var x=new SomeType()x
分配给循环中的任何其他对象,则所有先前的
SomeType
都不会被引用,因此符合垃圾收集的条件。换句话说,正如
所述,即使在对该对象执行实例方法时,也可以收集“this”。
很少会产生有意义的差异,但需要注意的是。@mjwills哦,这很有趣!