I have a DataGridView being regularly populated via data-bound objects, and the number of rows can potentially become large, say many thousands during a 'logging cycle'.
When a new 'logging cycle' begins, the grid is cleared because the underlying datasource is cleared and the process begins again.
This is all fine, but because the prev开发者_JAVA百科ious run takes some time, all those previous rows have become Generation 2 objects, and only garbage collected on a full GC.
However, it takes TWO full GC's to clear them out because the first one sends them all to the finalizer queue. This means that they hang around twice as long hogging memory.
Using reflector, I see that DataGridViewRow does not have a finalizer method, but it does inherit from a DataGridViewBand object, which does - and it calls GC.SuppressFinalize(this) via it's public Dispose() method.
So my question is - why do my DataGridViewRows not get collected on the first full GC and make it onto the finalizer queue awaiting another one?
(My assumptions here are that any object without a finalizer should not get placed onto the finalizer queue, and any object that does have one but calls GC.SuppressFinalize will also not be placed on the queueo. Am I right in this assumption?)
Thanks.
The call to GC.SuppressFinalize(this)
essentially tells the GC that the cleanup behaviors that occur during finalization have already happened (via the call to Dispose()
) and that it doesn't need to perform the finalization again. This has no bearing on whether or not the object is placed on the finalization queue.
Any time a finalizable object is instantiated (new
ed), it is placed on the finalization queue. The finalization queue is only processed during every full GC collection (Gen2 collection). One of the problems with finalizable objects is that they will survive at least one extra GC cycle before they are actually collected.
If you don't dispose your objects, then they will not have finalisation suppressed.
精彩评论