1

我有一个通过数据绑定对象定期填充的 DataGridView,并且行数可能会变大,例如在“日志记录周期”期间有数千行。

当一个新的“记录周期”开始时,网格被清除,因为底层数据源被清除并且该过程再次开始。

这一切都很好,但是因为之前的运行需要一些时间,所有之前的行都变成了第 2 代对象,并且只有在完整 GC 上进行垃圾收集。

但是,需要两次完整的 GC 才能清除它们,因为第一个将它们全部发送到终结器队列。这意味着它们占用内存的时间是原来的两倍。

使用反射器,我看到 DataGridViewRow 没有终结器方法,但它确实继承自 DataGridViewBand 对象,它确实 - 它通过它的公共 Dispose() 方法调用 GC.SuppressFinalize(this)。

所以我的问题是 - 为什么我的 DataGridViewRows 没有在第一次完整 GC 时被收集并进入等待另一个队列的终结器队列?

(我在这里的假设是,任何没有终结器的对象都不应该放在终结器队列中,并且任何有终结器但调用 GC.SuppressFinalize 的对象也不会放在队列中。我在这个假设中正确吗?)

谢谢。

4

2 回答 2

3

调用GC.SuppressFinalize(this)本质上告诉 GC 在终结期间发生的清理行为已经发生(通过调用Dispose())并且它不需要再次执行终结。这与对象是否放置在终结队列中无关。

任何时候一个可终结对象被实例化(newed),它都会被放置在终结队列中。最终队列仅在每次完整 GC 收集(Gen2 收集)期间处理。可终结对象的问题之一是它们在被实际收集之前至少会存活一个额外的 GC 周期。

于 2009-10-07T19:26:25.183 回答
0

如果您不处置您的对象,那么它们将不会被抑制。

于 2009-10-07T19:19:23.653 回答