I can guess ... and this is really just a guess. According to Eric, do not break rules like this :) This is an assumption only for the sake of idle speculation and interest.
I suspect there are two data structures:
- Finalization Queue
- Object Title
When the GC notices that an object has the right to garbage, I suspect that it checks the object header and adds a link to the completion queue. Your SuppressFinalization calls prevent this behavior.
Separately, the stream of the finalizer passes through the finalization queue and calls the finalizer for everything that it finds. Your calls to ReRegisterForFinalize bypassed in the usual way when the link ends in the queue and adds it directly. SuppressFinalization does not remove the link from the queue - it only stops the link to add to the queue in the usual way.
All this explains the behavior that you see (and which I reproduced). This also explains why, when I delete the SuppressFinalization calls, I end up looking at the trigger finalizer, because in this case the “normal” path adds a link to the finalization queue.
source share