Re: Threads & Garbage Collection
From: J.Marsch (jeremy_at_ctcdeveloper.com)
Date: 04/27/04
- Next message: James Hadwen: "Reflection, FieldInfo and ref"
- Previous message: Niki Estner: "Re: how to do a multiple inheritance - like"
- In reply to: Martin Maat: "Threads & Garbage Collection"
- Next in thread: Martin Maat: "Re: Threads & Garbage Collection"
- Reply: Martin Maat: "Re: Threads & Garbage Collection"
- Messages sorted by: [ date ] [ thread ]
Date: Tue, 27 Apr 2004 11:53:08 -0500
Martin:
I'm not sure that the behavior that you are seeing affects Garbage
collection as a whole -- rather, just the object that owns the method that
the thread runs.
1 fact that might interest you: Even in unmanaged applications (like C++ or
Delphi), if you let a thread "run away", without exiting it, it will hold
your process open.
Now, here's what I _think_ is going on in .Net: (why your object stays
alive):
Your object encapsulates the thread, right? So, the delegate that you
passed to the System.Thread's constructor is an instance member of your
manager object object, right?
A delegate contains a member called Target. Target is a reference to the
object that has the method that is being invoked by the delegate. So, when
you construct the thread, and you pass it a ThreadStart delegate, you are
giving out a reference to your object. So, there is no (or very little)
magic going on here. If I were going to place bets, I'd guess that it goes
something like this:
You have an O/S thread that is alive. It somehow keeps alive a reference to
the System.Threading.Thread object that manages it (this part might be
magic, but I though that I read somewhere that a reference to the Thread
Object is put in TLS on the thread that it manages). The thread object
holds a reference to a delegate (your ThreadStart delegate), which, in turn,
references your management object (through the Target property).
If that's right, there is no special GC behavior going on, there is just a
valid reference to your management object until the thread goes away. So,
your object is held in memory.
Facts vs hypothesis:
Fact: I know for a fact that a delegate will hold its target (the owner of
the method that will be invoked) in memory. This is well tested, documented
behavior.
Fact: I know that you hand a delegate to the Thread object in the
constructor.
Hypothesis: It's pretty likely that the Thread Object holds on to your
delegate for its lifetime. Therefore the target object cannot be eligible
for collection until the Thread object is eligible for collection
Hypothesis: I'm pretty sure that the ThreadObject is kept alive at least
until thread that it manages exits (I'm basically positive of this, but I
haven't decompiled the code, so I won't call it a fact);
Conclusion: The System.Thread stays alive until the thread is exited. The
System.ThreadObject holds reference to your management object (through a
delegate). So, your management object cannot be released from memory until
the thread exits.
"Martin Maat" <dummy@somewhere.nl> wrote in message
news:108sg684n9rd4ce@corp.supernews.com...
> I am puzzled.
>
> I have this object that uses a thread. The thread is encapsulated by the
> object, the object has Start and Stop methods to enable the client to
start
> or stop the thread.
>
> I found that the object will not be garbage collected while the thread is
> running. Fair enough, the documented explanation is that the GC compresses
> objects on the heap and needs to update references, the references will be
> invalid for a couple of moments which could be a problem if any thread is
> still using them while the GC is at work. So I have to stop my object
> explicitely before the application shuts down. In fact, if I don't, the
> application will not shutdown at all, the CLR will probably be waiting for
> me to stop the thread so it can do its final cleanup. Like I said, fair
> enough.
>
> But hey... This means that any applicaon that has some background thread
> running (which is not uncommon) will _never_ be subject to garbage
> collecting while it is running. This can't be right. It is a very common
> design pattern to have a modest background thread running that
periodically
> does some useful things and then goes to sleep for a couple of
milliseconds.
> Does this prevent the GC to kick in at all on the application's resources?
> It seems so, the finalizer of my object does not kick in while the thread
is
> running.
>
>
> What is true here and how do I go about it? It would help if there were a
> way for the thread to say "Hey, GC, I will enter a safe state now just to
> allow you to do your stuff. When you're done, wake me up again, okay?" But
I
> haven't found a way to do that (bluntly calling GC.Collect() from the
thread
> does not make any difference). So I am probably missing something. What is
> happening? Is there really no garbage collection for applications that do
> not take down all their threads on a regular basis?
>
> Martin.
>
>
- Next message: James Hadwen: "Reflection, FieldInfo and ref"
- Previous message: Niki Estner: "Re: how to do a multiple inheritance - like"
- In reply to: Martin Maat: "Threads & Garbage Collection"
- Next in thread: Martin Maat: "Re: Threads & Garbage Collection"
- Reply: Martin Maat: "Re: Threads & Garbage Collection"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|