方法本地 .NET 对象何时符合 GC 的条件?



>假设我有一个这样的C#方法:(显然不是真正的代码(

byte[] foo()
{
var a = MethodThatReturns500mbObject();
var b = MethodThatReturns200mbObject(a);
byte[] c = MethodThatReturns150mbByteArray(b);
byte[] d = UnwiselyCopyThatHugeArray(c);
return d;
}

正如您可以通过命名猜到的那样,通过这些方法返回的对象是巨大的。每个对象总共需要数百兆字节的RAM,尽管前两个对象由数百万个较小的对象组成,而不是像后两个数组那样由一个巨大的块组成。

我们很快会将其优化为流式处理解决方案,但与此同时,我想确保至少在执行代码以生成后续对象时不会阻止早期对象的 GC

。我的问题是:一旦 MethodThatReturns200mbObject(a( 返回,反对a是否有资格获得 GC? 如果没有,让 GC 知道有 500MB 存在等待它的最佳方法是什么?

我问题的核心是 .NET GC 对"此对象没有引用"的确定是否足够聪明,知道aMethodThatReturns200mbObject(a)返回后无法引用。 尽管var a理论上仍可用于以后的代码,但该方法第二行下方的任何地方都不会引用a。 理论上,编译器可以让 GC 知道a是未引用的。但在实践中,我不确定它的行为方式。你知道吗?

这篇文章用例子来解释它。

理论上,编译器可以让 GC 知道 a 是未引用的。但在实践中,我不确定它的行为方式。你知道吗?

正确答案是取决于项目配置 对象最终是否符合垃圾回收条件 的方法。如何时需要使用 GC 中所述。保持活力? (这也描述了GC的目的。保持活力 - 简而言之,它是一个 引用或"使用"变量的方式,确保 优化器不会优化使用(,垃圾收集器可能会 决定在对象无法被任何人使用时立即收集它们 不再执行代码。这很可能发生在以下情况下: 访问引用(在编译时(是有效的,但没有这样的 代码已编写。

但是,在调试模式下编译和执行代码时,编译器 防止这种情况发生以简化调试。结果, 我们的测试方法的正确实现包括预处理器 命令:

另一个很好的阅读 什么时候我需要使用 GC。保持活力?

最新更新