Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / July 2004

Tip: Looking for answers? Try searching our database.

GC SuppressFinalize and ReRegisterForFinalize

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Priyesh - 25 Jul 2004 20:11 GMT
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.
}
"Chris Lyon [MSFT]" - 27 Jul 2004 01:04 GMT
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
[quoted text clipped - 48 lines]
>    // two calls to Finalize are still performed.
>}

Signature

This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm

Note:  For the benefit of the community-at-large, all responses to this message are best directed to the newsgroup/thread from which they originated.

Priyesh - 27 Jul 2004 15:20 GMT
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.

> 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
[quoted text clipped - 52 lines]
> >    // two calls to Finalize are still performed.
> >}

originated.
"Chris Lyon [MSFT]" - 27 Jul 2004 17:28 GMT
Hi Priyesh

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
no added effect, regardless of how many times obj is on the queue.

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.

Hope that helps
-Chris

--------------------
>From: "Priyesh" <PriyeshPadmavilasom@cougarmtn.com>
>References: <ONj5JvncEHA.3480@TK2MSFTNGP11.phx.gbl> <V8GuP12cEHA.1520@cpmsftngxa10.phx.gbl>
[quoted text clipped - 123 lines]
>message are best directed to the newsgroup/thread from which they
>originated.

Signature

This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm

Note:  For the benefit of the community-at-large, all responses to this message are best directed to the newsgroup/thread from which they originated.

Priyesh - 27 Jul 2004 18:51 GMT
Hi Chris,
Thanks for the reply. Here is what i understand from your explanation.

1. The finalization queue will keep on adding references to the same object
to match ReRegisterForFinalize calls on the same object.

2. SuppressFinalize will set the "run my finalizer bit" in the obj. When GC
reaches a reference
in the finalization queue, it checks this bit and if the bit is not set,
wont move that to the f-reachable. GC would set the bit on the object so
that the object references pending in the finalization queue will be moved
to f-reachable and eventually the Finalize method will be called.

Please tell me if i understood it right.

Thanks
Priyesh

> Hi Priyesh
>
> 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
> no added effect, regardless of how many times obj is on the queue.
>
> 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.
>
[quoted text clipped - 15 lines]
> >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
[quoted text clipped - 110 lines]
> >message are best directed to the newsgroup/thread from which they
> >originated.

rights. Use of included script samples are subject to the terms specified at
> http://www.microsoft.com/info/cpyright.htm
>
> Note:  For the benefit of the community-at-large, all responses to this
message are best directed to the newsgroup/thread from which they
originated.
"Chris Lyon [MSFT]" - 27 Jul 2004 23:12 GMT
Hi Priyesh

1. Yes, that's right.

2. Yes.  SuppressFinalizer sets the "run my finalizer" bit to false, and that reference is removed from the queue, at which point the GC resets the bit to true.  Now when the next
reference to the same object is encountered on the queue, the object is moved to the f-reachable queue where its finalizer gets run.

I think we're on the same page now :)

-Chris

--------------------

>Hi Chris,
>Thanks for the reply. Here is what i understand from your explanation.
[quoted text clipped - 202 lines]
>message are best directed to the newsgroup/thread from which they
>originated.

Signature

This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm

Note:  For the benefit of the community-at-large, all responses to this message are best directed to the newsgroup/thread from which they originated.

Priyesh - 28 Jul 2004 00:10 GMT
Thankyou. I really appreciate it.

> Hi Priyesh
>
> 1. Yes, that's right.
>
> 2. Yes.  SuppressFinalizer sets the "run my finalizer" bit to false, and that reference is removed from the queue, at which point the GC resets the
bit to true.  Now when the next
> reference to the same object is encountered on the queue, the object is moved to the f-reachable queue where its finalizer gets run.
>
[quoted text clipped - 206 lines]
> >>
> >rights. Use of included script samples are subject to the terms specified
at
> >> http://www.microsoft.com/info/cpyright.htm
> >>
> >> Note:  For the benefit of the community-at-large, all responses to this
> >message are best directed to the newsgroup/thread from which they
> >originated.

rights. Use of included script samples are subject to the terms specified at
> http://www.microsoft.com/info/cpyright.htm
>
> Note:  For the benefit of the community-at-large, all responses to this
message are best directed to the newsgroup/thread from which they
originated.

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.