我正在对我的代码运行一些基准测试,我想确保在我的一个基准测试期间不会发生垃圾收集,因为它正在清理先前测试的混乱。我认为我的最好的机会是在开始基准测试之前强制收集。
所以我在基准测试开始之前调用GC.Collect(),但不确定收集是否继续在单独的线程中运行等,并立即返回。如果它确实在BG线程上运行,我想知道如何同步调用它或者至少等待它完成收集。
答案 0 :(得分:11)
正如MSDN所述 - 使用此方法尝试来回收所有无法访问的内存。
无论如何,如果确实启动了垃圾收集,你应该等到所有的终结者完成开始基准测试之前。
GC.Collect();
GC.WaitForPendingFinalizers();
答案 1 :(得分:10)
从 .NET Framework 4.5 ,您可以指定GC集合是否应该阻止:
GC.Collect(GC.MaxGeneration, GCCollectionMode.Optimized, blocking: true);
或
GC.Collect(GC.MaxGeneration, GCCollectionMode.Default, blocking: true);
GCCollectionMode.Default
目前默认为GCCollectionMode.Forced
有关详细信息,请参阅:
答案 2 :(得分:2)
如果您想对代码进行基准测试,则应该在多次迭代过程中进行平均分析。首先运行GC时,您永远无法保证。
答案 3 :(得分:2)
你应该假设:
因此,你要做的几次迭代测试,删除最高和最低(假设它们都是吸虫)并平均剩下的。这将为您提供有意义的比较。
答案 4 :(得分:-1)
.Net中GC的工作方式是停止所有线程(至少是完整集合的一部分,这是GC.Collect()
所做的)。所以你可以说它是非常同步的,它不是只阻止一个线程,而是所有线程。调用GC.Collect()
将执行收集并在完成后返回,因此,GC.Collect()
是同步运行它的方式。
有一个与GC相关的部分在后台线程上运行 - 终结器。如果要在运行基准测试之前确保所有终结器都已完成,并且实际收集了所有已完成的对象,请使用:
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
话虽如此,没有办法确保GC不会运行。我不明白为什么要那样做。例如,如果您的代码创建了大量临时对象,那么GC应该是您的基准测试的一部分,无论好坏,您都不应该尝试排除它。