No, there's no reference counting involved on the finalization queue. SuppressFinalize(obj) affects the first reference to obj on the queue, so calling it several times in a row has
The finalization queue doesn't have a seperate structure, rather a (strong) reference to the object in memory. In the object's header is the "run my finalizer" bit. When
suppressis called, the GC scans the queue from the front and and stops at the first reference to obj (when called again, it starts from the front of the queue again). That bit is set
in the header of the object obj points to. When reregister is called on obj, another reference to the object is placed at the end of the (FIFO) queue), so Suppress will never reach
past the first reference (which is why, as Richter states, you cannot balance out several calls to Rereg with Suppress).
The only I can think of to remove all pending finalization requestsis to have a suppress after every call to reregister. Short of that, maybe setting a flag in your finalizer to say
your object has already been finalized would remove redundant cleanup, but wouldn't stop the object from being put on the queue.
>From: "Priyesh" <PriyeshPadmavilasom@cougarmtn.com>
>References: <ONj5JvncEHA.3480@TK2MSFTNGP11.phx.gbl> <V8GuP12cEHA.1520@cpmsftngxa10.phx.gbl>
>Subject: Re: GC SuppressFinalize and ReRegisterForFinalize
>Date: Tue, 27 Jul 2004 07:20:18 -0700
>Lines: 126
>X-Priority: 3
>X-MSMail-Priority: Normal
>X-Newsreader: Microsoft Outlook Express 6.00.2800.1437
>X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1441
>Message-ID: <uS5cvV#cEHA.244@TK2MSFTNGP12.phx.gbl>
>Newsgroups: microsoft.public.dotnet.framework.clr
>NNTP-Posting-Host: wireless-216-222-33-194.boi.velocitus.net 216.222.33.194
>Path: cpmsftngxa10.phx.gbl!TK2MSFTFEED01.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP12.phx.gbl
>Xref: cpmsftngxa10.phx.gbl microsoft.public.dotnet.framework.clr:11372
>X-Tomcat-NG: microsoft.public.dotnet.framework.clr
>
>Thanks for your explanation and the points about the correctness of the
>article. I understand that this is a theoretical scenario to explain some of
>the GC functionality available.
>
>I was thinking that there is some sort of reference counting mechanism for
>the same object in the finalization queue. Since the example operates on a
>single object, i got myself into thinking SuppressFinalize call on that
>object would affect that one object and would not let any further Finalize
>calls. From your explanation, it seems that the finalization queue contains
>a separate structure which has a pointer to the object to be finalized.
>
>When ReRegisterForFinalize is called on an object, is there another memory
>structure created in the finalization queue?
>If so, how does the SuppressFinalize determine which reference in the queue
>to apply the suppress to? (Does it apply to the first reference in queue all
>the time?)
>Is there a way to get rid of all pending finalization requests?
>
>I would really appreciate your follow up on these questions.
>
>
>
>""Chris Lyon [MSFT]"" <clyon@online.microsoft.com> wrote in message
>news:V8GuP12cEHA.1520@cpmsftngxa10.phx.gbl...
>> Hi Priyesh
>>
>> In the article you point to, Jeffrey explains that SuppressFinalize sets a
>flag in the object to not run the finalizer. So if you have 3 references to
>the same object on the finalization
>> queue, the GC will set the bit when it reaches that object on the queue,
>then discard it. After that, when the GC reaches the object a second time
>onthe queue, the flag gets reset
>> "this flag is reset when the runtime determines that it's time to call a
>Finalize method", so that's why the finalizer is run twice in the sample you
>provided.
>>
>> That being said, I can't think of a valid scenario when someone would want
>to reregister a live object, so I don't expect this scenario cropping up
>much in real life.
>>
>> Also, for what it's worth, that article is pretty outdated, and contains
>some inaccurate information. For example, it's not possible to override
>Finalize in C#, and it's impossible to
>> explicitly call an object's Finalization method. Also, an object's
>parent's finalizer is called automatically (check out the IL to see for
>yourself).
>>
>> Hope that helps
>> -Chris
>>
>>
>> --------------------
>> >From: "Priyesh" <PriyeshPadmavilasom@cougarmtn.com>
>> >Subject: GC SuppressFinalize and ReRegisterForFinalize
>> >Date: Sun, 25 Jul 2004 12:11:35 -0700
>> >Lines: 39
>> >X-Priority: 3
>> >X-MSMail-Priority: Normal
>> >X-Newsreader: Microsoft Outlook Express 6.00.2800.1437
>> >X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1441
>> >Message-ID: <ONj5JvncEHA.3480@TK2MSFTNGP11.phx.gbl>
>> >Newsgroups: microsoft.public.dotnet.framework.clr
>> >NNTP-Posting-Host: wireless-216-222-33-194.boi.velocitus.net
>216.222.33.194
>> >Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP11.phx.gbl
>> >Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.framework.clr:11293
>> >X-Tomcat-NG: microsoft.public.dotnet.framework.clr
>> >
>> >I am having trouble understanding the code below.
>> >(From
http://msdn.microsoft.com/msdnmag/issues/1100/GCI/ Figure 9)
>> >
>> >I am looking for an explanation about how the SuppressFinalize calls
>work.
>> >From reading the documentation, i get the idea that SuppressFinalize
>would
>> >remove the obj from the finalization table, so wouldnt it remove all the
>> >entries for a obj as i am operating on the same object? If it toggles a
>flag
>> >on the obj, how come finalize gets called two times?
>> >
>> >void method() {
>> > // The MyObj type has a Finalize method defined for it
>> > // Creating a MyObj places a reference to obj on the finalization
>table.
>> > MyObj obj = new MyObj();
>> >
>> > // Append another 2 references for obj onto the finalization table.
>> > GC.ReRegisterForFinalize(obj);
>> > GC.ReRegisterForFinalize(obj);
>> >
>> > // There are now 3 references to obj on the finalization table.
>> >
>> > // Have the system ignore the first call to this object's Finalize
>> > // method.
>> > GC.SuppressFinalize(obj);
>> >
>> > // Have the system ignore the first call to this object's Finalize
>> > // method.
>> > GC.SuppressFinalize(obj); // In effect, this line does absolutely
>> > // nothing!
>> >
>> > obj = null; // Remove the strong reference to the object.
>> >
>> > // Force the GC to collect the object.
>> > GC.Collect();
>> >
>> > // The first call to obj's Finalize method will be discarded but
>> > // two calls to Finalize are still performed.
>> >}
>> >
>> >
>> >
>>
>>
>> --
>>