I was reading about the GC in the book CLR via C#
, specifically about when the CLR wants to start a collection. I understand that it has to suspend the threads before a collection occurs, but it mentions that it has to do this when the thread instruction pointer reaches a safe point. In the cases where it's not in a safe point, it tries to get to one quickly, and it does so by hijacking
the thread (inserting a special function pointer in the thread stack). That's all fine and dandy, but I thought managed threads by default were safe?
I had initially thought it might have been referring to unmanaged threads, but the CLR lets unmanaged threads continue executing because any object being used should have been pinned anyway.
So, what is a safe point
in a managed thread, and how can the GC determine what that is?
EDIT:
I don't think I was being specific enough. According to this MSDN article, even when Thread.Suspend
is called, the thread will not actually be suspended until a safe point
is reached. It goes on to further state that a safe point
is a point in a threads execution at which a garbage collection can be performed.
I think I was unclear in my question. I realize that a Thread can only be suspended at a safe point and they have to be suspended for a GC, but I can't seem to find a clear answer as to what a safe point is. What determines a point in code as being safe?
'Safe Points' are where we are:
Not inside p/invoke'd call (in managed code).Not running unmanaged code in the CLR.Point #5 is a bit confusing, but there are times when the memory tree will not be walkable. For example, after optimization, the CLR may new an Object and not assign it directly to a variable. According to the GC, this object would be a dead object ready to be collected. The compiler will instruct the GC when this happens to not run GC yet.
Here's a blog post on msdn with a little bit more information: http://blogs.msdn.com/b/abhinaba/archive/2009/09/02/netcf-gc-and-thread-blocking.aspx
EDIT: Well, sir, I was WRONG about #4. See here in the 'Safe Point' section. If we are inside a p/invoke (unmanaged) code section then it is allowed to run until it comes back out to managed code again.
However, according to this MSDN article, if we are in an unmanaged portion of CLR code, then it is not considered safe and they will wait until the code returns to managed. (I was close, at least).