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