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哦,这很有趣!