Cha*_*sis 5 .net c# garbage-collection
根据垃圾收集基础知识,除了触发垃圾收集的线程之外,所有线程在垃圾收集期间都会被挂起。由于终结器是在垃圾收集过程中调用的,因此我希望线程被挂起,直到所有终结器都被执行。因此,我希望以下代码“需要更长的时间”才能完成。相反,它会抛出一个System.OutOfMemoryException. 有人可以详细说明为什么会发生这种情况吗?
class Program
{
class Person
{
long[] personArray = new long[1000000];
~Person()
{
Thread.Sleep(1);
}
}
static void Main(string[] args)
{
for (long i = 0; i < 100000000000; i++)
{
Person p = new Person();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Person当终结器执行时,堆上新对象的创建是否也会被暂停?
代码取自考试参考 70-483 C# 编程 (MCSD)
好的,所以我做了一些更多的研究,结果发现垃圾收集器不会同步调用终结器。它执行以下操作:
之后,终结器线程开始与应用程序的其余部分一起在后台运行,并调用其队列中每个对象的终结器。这就是我所描述的问题出现的地方。Person堆中的对象将其引用移动到终结队列中,但在终结实际发生之前,它们的内存不会释放。终结在应用程序运行时发生(并且在堆上创建更多对象)。
在终结结束之前,垃圾收集器无法回收内存,因此,主线程(创建对象)和 GC Finalizer 线程(调用终结器)之间会出现竞争条件。
我还通过调试 IL 代码并查看上述两个线程之间的执行切换来确认此行为。
我还在 SO 上发现了这个问题,它描述了相同的行为。
| 归档时间: |
|
| 查看次数: |
781 次 |
| 最近记录: |