是否可以手动标记/取消标记对象以进行垃圾回收?

时间:2013-12-18 09:45:49

标签: c# garbage-collection weak-references

大多数资源声明垃圾收集器根据引用自行计算出来并且我不应该弄乱它。

我想知道我是否可以明确地告诉垃圾收集器它可能在保留引用的同时处理对象。

我想做的是告诉垃圾收集器我目前不再需要一个对象(但可能会再次),然后在稍后的时候(如果)我再次需要该对象我想检查如果已经处理掉了。如果它只是我重新创建它,如果它没有我想从垃圾收集中“取消标记”它,直到我再次完成它。

这可能吗?

我计划实现与Lazy<T>类类似的东西。伪代码:

obj = new DisposeIfNecessary<LargeObject>(() => InitLargeObject());
obj.DoSomething(); // Initializes obj using InitLargeObject()
obj.DisposeIfNecessary(); // This is where the magic happens

... // obj might get disposed at some point

obj.DoAnotherThing(); // Might or might not call InitLargeObject() again
obj.Dispose(); // I will not need it again

1 个答案:

答案 0 :(得分:9)

WeakReference类完全符合您的要求,使用IsAlive属性在使用之前检查状态。

您可以通过Target属性再次获得对它的“强烈”引用,这会影响引用计数并阻止其有资格进行收集。

另请注意,Dispose与垃圾收集没有直接关系,因此处置项目(取决于Dispose实现)可能会使其无法使用 - 但同样,这与此无关GC。在一般的实践说明中,正如@HansPassant所提到的那样,在一个项目上调用Dispose(或者通常是任何声称要处置的东西),然后再尝试再次使用它是一种代码味道(或者其他开发人员将会出错期望Dispose是一个最后调用的方法,从那时起将对象标记为不可用。)

WeakReference类不负责重新创建收集的对象,但与IsAlive结合使用,您可以自己处理该逻辑。

此外,就评论中的要点而言,GC在决定何时收集它时试图将WeakReference项留到最后; WeakReference并没有做任何聪明的事情。如果它符合条件,它将像运行中的其他对象一样收集底层对象 - 没有特殊处理,绝对没有“缓存”行为。