C# 将dispose中的成员置零以控制内存使用

C# 将dispose中的成员置零以控制内存使用,c#,memory-management,dispose,C#,Memory Management,Dispose,对象列表A保存在缓存中。在某一点上,这些对象被传递,并使用a,B属性。B是一个大型数据结构A需要保存在缓存中,但在某一点上不需要B,因为它很大,我们希望让它被垃圾收集 设置a.B=null的上的Dispose方法是否允许垃圾收集器收集该对象,如果没有其他对象包含对B的引用(即,当我们不再需要B时,我们将调用a上的Dispose,或者可以使用using语句来实现相同的效果) 在此上下文中,Dispose用于控制托管对象的生存时间,即CG可以释放托管对象的时间。Dispose始终用于控制托管对象的生

对象列表
A
保存在缓存中。在某一点上,这些对象被传递,并使用
a
B
属性。B是一个大型数据结构
A
需要保存在缓存中,但在某一点上不需要
B
,因为它很大,我们希望让它被垃圾收集

设置
a.B=null
的上的
Dispose
方法是否允许垃圾收集器收集该对象,如果没有其他对象包含对
B
的引用(即,当我们不再需要
B
时,我们将调用
a
上的Dispose,或者可以使用using语句来实现相同的效果)

在此上下文中,Dispose用于控制托管对象的生存时间,即CG可以释放托管对象的时间。

Dispose始终用于控制托管对象的生存期-调用Dispose后访问对象是一个坏主意,如果您这样做,许多BCL对象将抛出异常。不引用对象是垃圾收集的先决条件,但GC足够智能,可以检测图形

例如,如果A是孤立的,并且没有其他任何东西包含对B的引用,那么B也会被收集。另一方面,如果其他东西引用了B,那么a就不是真正的孤儿,也不会被收集

取消引用不会强制垃圾收集,也不应该尝试强制垃圾收集。垃圾收集器足够聪明,只有在内存压力较大的情况下才能运行垃圾收集,因为释放代价很高

更新

看起来实际的问题是“如果我想在不释放A的情况下释放A.B,调用A.Dispose()可以吗?”答案是“不,决不”


A.Dispose
意味着
A
无论出于何种目的都是死的。最好添加一个名为
A.CloseB()
的方法,该方法实际调用
B.Dispose()
然后将其设置为
null
,并在必要时让GC收集它。

Dispose
上预期会有一些契约。它用于处理非托管资源。它也可能在其他上下文中被调用(可能可以,但只是可能,为什么要冒险。)为什么不干脆创建另一个方法
void DisposeB(){B=null;}
?@luk32这不正确。它并不意味着只处理非托管资源,事实上,显式调用它将处理所有托管对象。典型的实现模式(使用
dispose(bool)
方法)是使所有引用为空,但仅在显式调用时对托管对象调用Dispose。检查详细信息在释放后将其放入缓存是一种非常强烈的代码味道。永远不要修改IDisposable契约。只需创建自己的契约即可。@HansPassant Yes Ok agree.@PanagiotisKanavos agree-Dispose不仅用于非托管控件,而且用于非托管控件托管的fetime控件。但我认为我在这里扩展了它的使用范围,因为a还没有完成。真的,我只想要a.FreeMemory()我想。有一件事需要注意-
Dispose
在这个例子中应该放在
B
上并调用。可能通过
a
上的方法访问,但它是
B
被处理的,以澄清a不是孤立的,它仍然在使用中-但是在不再需要大型B的上下文中。此时,代码不会引用然后我同意Hans Passant的观点,那是一种非常强烈的代码气味,这个问题需要重新编写。不要调用a.Dispose,添加一个名为
CloseB
的方法。