大多数资源声明垃圾收集器根据引用自行计算出来并且我不应该弄乱它。
我想知道我是否可以明确地告诉垃圾收集器它可能在保留引用的同时处理对象。
我想做的是告诉垃圾收集器我目前不再需要一个对象(但可能会再次),然后在稍后的时候(如果)我再次需要该对象我想检查如果已经处理掉了。如果它只是我重新创建它,如果它没有我想从垃圾收集中“取消标记”它,直到我再次完成它。
这可能吗?
我计划实现与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
答案 0 :(得分:9)
WeakReference
类完全符合您的要求,使用IsAlive
属性在使用之前检查状态。
您可以通过Target
属性再次获得对它的“强烈”引用,这会影响引用计数并阻止其有资格进行收集。
另请注意,Dispose
与垃圾收集没有直接关系,因此处置项目(取决于Dispose
实现)可能会使其无法使用 - 但同样,这与此无关GC。在一般的实践说明中,正如@HansPassant所提到的那样,在一个项目上调用Dispose
(或者通常是任何声称要处置的东西),然后再尝试再次使用它是一种代码味道(或者其他开发人员将会出错期望Dispose
是一个最后调用的方法,从那时起将对象标记为不可用。)
WeakReference
类不负责重新创建收集的对象,但与IsAlive
结合使用,您可以自己处理该逻辑。
此外,就评论中的要点而言,GC在决定何时收集它时试图将WeakReference
项留到最后; WeakReference
并没有做任何聪明的事情。如果它符合条件,它将像运行中的其他对象一样收集底层对象 - 没有特殊处理,绝对没有“缓存”行为。