.NET allows creating Windows Services which are commonly used for unattended services such as Remoting containers.

For some reason, when using a Windows Services as a container for your Remoting application or as just a Windows Service that perfrom various tasks, the GC used is the workstation GC.

We have previously talked a bit about the difference between the workstation GC and the server GC but I’ll explain a bit about them again.

Workstation GC
The workstation GC is, as its name applies, is used in a workstation scenario. It is optimized for single CPU machines and for desktop application by using the main thread to perform the GC.
It uses 16mb segments that it reserves and sub allocates.

It has an option called “Concurrent GC” which allows the GC to run on a dedicated thread.

Server GC
The Server GC It is optimized for server operations and works only on a multi processor machines (CPUs that has Hyper Threading enabled are considered as two CPUs).

It has a GC heap per CPU and a thread per CPU that performs the garbage collection.
It uses 32Mb segments that it reserves and sub allocates.

All of these features make the Server GC more appropriate for demanding server applications due to its higher throughput.

Who uses the Server GC?
The only containers that use the Server GC by default are ASP.NET and COM+ (through Enterprise Services).

All other applications including Windows Services use the Workstation GC by default.

This means that even if you wrote a cool Windows Service in .NET that does cool stuff it may suffer from using a non optimized GC even though its a high throughput service that serves millions of users.

So, what can we do about it?
Before .NET Framework 1.1 SP1 you had to implement your own container for the CLR.
Since .NET Framework 1.1 SP1 you can just add to your app.config file the following tag and it will tell the GC to use the Server GC (of course, only if you have more than one CPU):

<configuration>
<runtime>
<gcserver enabled="true" />
</runtime>
</configuration>

You can read more about it (though not too much) in this Microsoft KB article.

For .NET Framework 1.0 you’ll still have to implement your own container for the CLR.
There are a bunch of these hangging around. A nice one is this one which is posted in The Code Project.


Just think about the fact that with one simple flag you can boost your Windows Service performance.

I was working today on figuring out some Managed C++ code with a friend from work (Oran Singer) and I just wanted to outline some of the oddities of the Managed C++ Destructors because I think it is important for everyone to understand how they work and what some of the quirks about them are.

We are still in the middle of figuring out something more serious (I will post on that later on).

I would like to “appologize” to the C#/VB.NET crowed in advance since this post is all about Managed C++ today a bit on its future, but I think it will be interesting none-the-less.

First of all, a Managed C++ class that had a destructor will include two additional methods due to the destructor:

  1. Finalize method
  2. __dtor method

Currently you cannot implement the finalize method in managed C++ directly like in C# by simply override it since it is defined as private protected in System::Object so the only way to do it is to add a destructor to the class.

This means that a Managed C++ class that has a destructor has a finalizer with all the implications of a .NET finalizer (I’ve written in more detail about finalizers here).

The __dtor is being called when you use the “delete” operator on a managed C++ class instance (IMPORTANT NOTE: You can only call “delete” on a managed C++ class instance that implements a destructor).

The implementation of the __dtor method is similar to an implementation one would put in a Dispose method when implementing the IDisposable interface. It has two function calls, one to GC.SuppressFinalize (so the finalizer thread will ignore calling the Finalize method of this instance) and a call to Finalize (to actually perform the destructor code).

Another interesting anecdote is that if you have a pure virtual class and you add a constructor to it, it must have a body even though this is a pure virtual class since there is always a virtual call to the base class’s destructor.

Looking a bit to the future, in Visual Studio 2005 (previously known as Whidbey) Visual C++ that generates managed code get a few new features that are a bit different in implementation than what we saw above.

First of all, when implementing only a destructor (“~MyClass()”) the compiler will actually fully implement the IDisposable interface and in certain cases will automatically call the Dispose method (in C# you would either use try..finally block and call the Dispose at the finally part or use the “using” keyword) in the following cases:

  • A stack based object goes out of scope
  • A class member’s enclosing object is destroyed
  • A delete is performed on the pointer or handle.

In addition to that you can explicitly implement a finalizer using the “!” tag (“!MyClass()”). That finalizer is subject to that usual finalizer rules we already know. The main advantage is that it will NOT run if you already called the destructor.

These new features allows improved control for a more deterministic cleanup and allows finer control on C++ managed objects that was previously not available.

I would like to thank Oran again for his help, mainly for forcing me to search some more on the subject and getting the idea to write this post.

Remeber a few posts ago that I talked about CorDbg, the managed debugger?
According to this post in Mike Stall’s blog (a fine blog, btw) its out of the SDK.

CorDbg was the first managed debugger that was written. It was written in native code since Interop in those days was still being written and was very unstable.
CorDbg also lacks features that are common in WinDbg such as extending it with extensions and instrumeting with it in a nice way.

Its hard (or even impossible according to this at Mike Stall’s blog) to implement a managed debugger in managed code for v1.1 (although I know there are a few people messing around with it as we speak, me included 😉 ). That is why CorDbg is the only viable managed debugger for production debugging for v1.1

To fill all of these gaps and to make things a lot more easier and more powerful here comes MDbg (ta-da).

MDbg is a managed deubugger fully written in C#. Its extendable by writing managed code to extend it, can be used to instrument code and is just so damn cool 😉

It gives you all the things you ever wanted from a production debugger and can also debug both .NET 1.1 and 2.0 code (to use it to debug 1.1 code you will still have to have the .NET 2.0 Runtime installed).

You can find out more information about MDbg here.
I am in the process of collecting some more information for a more elaborate post on MDbg and some of its features (probably a series of posts), so stay tuned.

In this post, I’ll talk about some issues that one must understand about mixing finalization and P/Invoke Interoping.

Usually, when you have a class that has an IntPtr as a member due to some P/Invoke code you implement a Finalizer and the IDisposable interface in which the necessary cleanup code will be implemented to release the unmanaged resources you have allocated.

The main problem starts when that same class has other member variables that are managed.
These managed member variables will not get collected until our class’ instance is finalized and that can generate memory pressure that is not really necessary if things are implemented correctly.

So, what can we do about it?

There are a few approaches that can help us minimize the effect of P/Invoking and finalizers:

  1. Don’t declare the IntPtr variable as a member variable.
  2. Create a class that wraps the IntPtr and P/Invoke code without declaring managed member variables.

Let’s examine both approaches.

The first approach talks about not declaring IntPtr variables as member variables. This means that if you have some function that needs to interop, delcare the IntPtr variable as a local variable, use it and clean everything up. This is the best approach but will only work if there are no (serious) performance penalties such as calling some heavy P/Invoked Windows API.

The second approach is a more viable one if there is a need to continuously call some unmanaged API such as ReadFile on a socket or file. In this case, writing a dedicated class that holds the reference to the unmanaged resource only and a finalizer and IDisposable would be a great way of making sure that it will not hold back the GC of other resources (not to mention it would be cleaner to have a dedicated class for wrapping such API 😉 ).

That class we have an IntPtr as a member variable and will have additional functions to manipulate the data that is being held behind that unmanaged resource.

By implementing one of the two approaches I’ve discussed above you can, quite easily, ease the memory pressure on your application with little change to your code and functionality.

In .NET Framework 2.0 that will come with Visual Studio 2005 (formerly known as Whideby) there is a new mechanism to handle such issues called SafeHandle. You can read more about it here, in this great post from the BCL Team Blog.

I will talk about SafeHandles in a subsequent post.

WinDbg is a native debugger and although using it combined with SOS to perform managed debugging is great, it sometimes lack the finesse that only a managed debugger can give.

CorDbg is a managed debugger that ships with the .NET Framework SDK. It was not written in managed code since it was the first managed debugger written in the early days of .NET when you couldn’t yet rely on managed code to produce a debugger that will debug it.

CorDbg knows and understand .NET better than WinDbg+SOS can. That is why you can better debug .NET applications with it.
For example, A simple scenario that is hard to do with WinDbg+SOS and very easy to do in CorDbg is to break only when specific .NET exceptions happen.
When I say specific I mean SPECIFIC, i.e., I can specifically specify that I want to ignore System.ThreadAbortException but not System.FileNotFoundException.

To do that all I need to do is run the following commands:

catch exception System.FileNotFoundException
ignore exception System.ThreadAbortException

WinDbg can only break (without adding sophisticated scripts to further analyze an exception) on CLR exceptions since all CLR exception has the same exception code.

Some more cool and useful things CorDbg can do includes:

  • Easily set a breakpoint in managed code (and we all know its not that nice to set a managed breakpoint in WinDbg using SOS) using the b[reak] command:b foo.cs:42 – will break in file foo.cs in line 42.
    b MyClass::MyFunction – will break at the start of MyClass::MyFunction
  • Disassembling to native or IL code using the dis[assemble] command.
  • Evaluate a function and using the f[unceval] command:f MyNamespace.MyClass::MyMethod – for static method
    f MyClass::MyMethod param1 param2 $result – for instance method. The result is stored in $result for further evaluations
  • Printing variables to see their content using their names (for local variables, only if debug symbols are available) using the p[rint] command instead of finding out their addresses to print them in WinDbg:
    p obj1.var1 – for variables inside objects
    p MyClass::MyStaticVar – for static variables
    p arr[2] – for print a specific cell in an array
  • Changing a variable value using the set command.
  • Setting the next line of execution by simply invoking setip [line number] (like you do with right-clicking in Visual Studio .NET)

As you can see, using a managed debugger like CorDbg can be a lot nicer and easier instead of WinDbg.

I heared unsubstantiated rumores that when Microsoft developers have problems with a certain build of Visual Studio they use CorDbg to figure out the problem or to debug instead of finding what the problem with Visual Studio is.

Visual Studio .NET 2005 will contain a new managed debugger that was written in managed code called MDbg. You can get it here (it required .NET Framework 2.0). MDbg has an extensions API so you can extened it just as you can extened WinDbg (but its even easier). It also features a nice simple GUI for those of you who doesn’t like to use the keyboard too much.

You can read more about MDbg in Mike Stall’s blog

I will dedicate another post to MDbg so stay tuned.

Yesterday my RSS client, RSSBandit, decided to stop working.
Luckly RSSBandit is a .NET application with source code, so I’ve decided to start debugging it.
It kept on failing when it tried to deserialize one of its configuration classes from Xml using the XmlSerializer class.

The XmlSerializer class generates a temporary assembly in its constructor according to the XmlMapping it receives, compiles it and loads it.
Sometimes there is a problem at compile time. The code is not actually compiled and you will get a FileNotFoundException exception just for calling “new XmlSerializer(typeof(MyClass))“.

While trying to resolve this issue I’ve stumbled upon two tools that can help you better understand the cause of the problem and at some scenarios might suggest a resolution.

The first tools is a command line too called XmlSerializerPreCompiler written by Chris Sells. You just specify the full path to the assembly and the type name to check and it will try to create an XmlSerializer passing the type to it and analyzing the error.

The second one is a GUI tool that was based on XmlSerializerPreCompiler called XmlPreCompiler written by Mathew Nolton.

Both tools comes with full source code.

While I didn’t have time to check their source code I did see one of the things they use to get more information about the temporary assembly that is being compiled on the fly when creating the XmlSerializer.
It seems that there is a configuration flag that you put in the app.config file (if you don’t have one, just create one that is named myprogram.exe.config, where myprogram is your executeable name).

Just add the following to your app.config file:

<configuration>

<system.diagnostics>

<switches>

<add value=”4″ name=”XmlSerialization.Compilation”>

</switches>

</system.diagnostics>

</configuration>
This option tells the XmlSerializer not to delete the temporary files created to generate the temp assembly. It will leave the .cs file it was trying to compile, a .cmdline file which has the command line parameters that are sent to the compiler and a .out file which has the full command line that was used to compile the .cs file.

All of these files are generated it your %USERPROFILE%\Local Settings\Temp folder (which is usually equivalent to %TEMP%) and by just adding the above flag in your app.config you can get the input that is used in the programs I’ve mentioned above and investigate on your own.

While all of these programs couldn’t help me in resolving what is wrong with RSSBandit (and for that matter, any thing that has the “new XmlSerializer(typeof(MyClass))” code in it that runs on my machine) I’d thought it would be nice to share this information with everyone.

Since I don’t have time to further analyze this and I need my daily RSS feed dose, I did the following things:

  1. Ran WinDbg and started RSSBandit through it.
  2. Set a breakpoint (we have discussed about setting a managed breakpoint before) on System.CodeDom.Compiler.CompilerResults.get_CompiledAssembly (this function is the one that tries to load the temp compiled assembly and will throw the exception I’m getting in RSSBandit since the temp assembly wasn’t compiled).
  3. When the breakpoint hit (and it does so a few times until RSSBandit finishes loading) I ran !dumpheap -type CompilerResults
  4. I dumped the CompilerResults object using !dumpobject
  5. I then took the address of the pathToAssembly member and used !dumpobject on it as well.
  6. I then took the path, went there, opened the file named [strange random chars].out (where [strange random chars] is a unique name for each such assembly), opened it, copied the command line and ran it to generate the assembly.
  7. Continued doing this until we never reach the breakpoint again.

What I did learn from this workaround is that the main problem is executing the compiler command to compile the assembly and that will be the point from which I will continue to troubleshoot this issue.

At least for now RSSBandit is working (though only through WinDbg 😉 ) and I can read my favorite RSS feeds.

The Monitor class in .NET is a pure managed implementation of a Critical Section. It is used to synchronize multiple threads’ access to a code block.

C#’s lock statement and VB.NET’s SyncLock statement are actually evaluated into a Try..Finally block that has Monitor.Enter at the start and Monitor.Exit inside the Finally block.

For example:

[C#]
lock(myObject)
{
// Some code requiring synchronization
}

[VB.NET]
SyncLock MyObject
' Some code requiring synchronization
End SyncLock


The actual code produced is:

[C#]
Monitor.Enter(myObject);
try
{
// Some code requiring synchronization
}
finally
{
Monitor.Exit(myObject);
}

[VB.NET]
Monitor.Enter MyObject
Try
' Some code requiring synchronization
Finally
Monitor.Exit MyObject
End Try

There are two major issues that should be considered when using the Monitor class (or C#’s Lock and VB.NET’s SyncLock):

  1. Monitor only works on Reference objects and NOT value types. This means you cannot use an Integer as the object to lock when entering a monitor because it wil be boxed and releaed right away, effectivly not synchronizing the code.
  2. Locking should always be performed on private or internal objects.

There are a great deal of samples floating around that locks the “this” (“Me” in VB.NET) object, which means you are using the current instance as the object that is used for locking.

If this object is a public one and is used or can be used by others (either inside your organization or outside, if you work in an organization to begin with 😉 ), if you lock this instance and that instance is also available to someone else, they might also use it for locking and essentially create a potential deadlock.

So, what should we do about that?

ALWAYS USE PRIVATE OR INTERNAL OBJECTS FOR LOCKS!

The best way to avoid a deadlock is to ALWAYS use private object for locking.

For example:

[C#]
public class LockClass
{
private static object myLock = new Object()
public function void DoIt()
{
lock(myLock)
{
// Some code block that is in
// need of a sync
}
}
}

[VB.NET]
Public Class LockClass
Private Shared MyLock As Object = New Object()

Public Sub DoIt()
SyncLock MyLock
' Some code block that is in
' need of a sync
End SyncLock
End Sub
End Class

Remeber these two guidelines mentioned above and you will save yourself a lot of time trying to find an elusive managed deadlock that is usually hard to reproduce.

From day 1, .NET presented an easy to use ThreadPool that will handle all of your queuing/dispatching needs.

While ThreadPool is a cool thing that saves you a lot of time dealing with multi threaded issues, one must be careful when using it and understand how it works and who else is using it to avoid common pitfalls.

Who Uses the ThreadPool?

  • Any asynchronous delegate invocation (BeginInvoke/EndInvoke pattern)
  • HttpWebRequest uses it internally to queue and dispatch web requests.
  • WebRequest uses it to dispatch the request
  • Some timers (like System.Threading.Timer).
  • The end user that uses Thread Pool directly.

The Problem

Consider a situation in which you have one of the above filling up the Thread Pool with queued items. Each queue item was implemeneted in a way that also uses the ThreadPool (either directly or by an async invocation). We then reach to a point where the ThreadPool is full and all of its requests are blocking and waiting to get some work done using the ThreadPool.

Bang! You are deadlocked! You have circular dependency that code that runs inside a ThreadPool worker thread is blocking because it runs a code that also needs the ThreadPool, but the ThreadPool is already full and it is also waiting to get a worker Thread to run on to of it.

Reaching this situation is quite easy under high load since by default, the ThreadPool is set to have 25 threads per CPU (A Hyper Threaded CPU is considered as two CPUs by .NET and the Operating System and therefore a ThreadPool running on that CPU will have 50 threads, 25 per CPU).

The Solution

There is actually more than one way of avoiding this situation:

  • Query the ThreadPool using ThreadPool.GetAvailableThreads to see if you should queue the item or not. If you can’t, either throw an exception or wait until you can use it (just don’t wait if you are on a Thread Pool worker thread, i.e. you are running inside an ASP.NET page 😉 We are trying to avoid that). This is a similar approach that .NET takes internally.
  • Avoidance – Don’t call this code from within a place that uses the ThreadPool such as from within ASP.NET or from within an Async call.
  • Implement your own ThreadPool instead of using .NET’s ThreadPool – This is not as easy as it sounds, though.

There is an additional solution but its ONLY applicable in the coming .NET 2.0 which is to specifically call ThreadPool.SetMaxThreads. By doing so you will be able to increase the amount of threads available to the ThreadPool.

NOTE: Do mind that having too many threads per CPU is not recommended since the Operating System will spend a lot of time just making sure they are not starved.

As we can see, ThreadPool is a great thing that saves us the time and effort of implementing a multi threaded pool with all of its synchronization and other thread related issues but we still must understand that it has its limitation and we need to understand how it works and what it do to avoid unnecessary deadlocks and/or strange behavior.

In the post about perfmon I’ve briefly mentioned the fact that you can utilize GC.Collect to find memory leaks.

By combining some custom code, WinDbg and SOS you can track most (if not all) of your managed memory leaks without buying a memory profiler.

The methodology is very simple and very easy to implement and use.
It involves taking serveral memory dumps at specific points and anaylzing the objects on the managed heap.

Preparing the data for analysis
Before we can start analyzing we need to prepare the data by doing the following things:

  • Prepare a call to GC.Collect. The exact code should look like this:
    GC.Collect();
    GC.WaitForPendingFinalizers();
    Just to be sure that everything is clean, call this code 3 times. This will ensure that everything, including all pending finalizers (objects that awaits for their finalizer to be called), are really gone.

    If this is a WinForms application, just add a button that will call the above code.
    If this is a Web application (ASP.NET or ASP.NET WebService) add a page called Collect.aspx with this code (If you don’t want to compile this into a code behind assembly, just download this page and place it in the root folder of the application).

  • Run the application and reach to a point before the area of code you wish analyze and take a memory dump using adplus.vbs -hang -p [process id].
    This dump will be used to show us what objects were already on the heap before we started the operation.
  • Run the operation we want to check for memory leaks and after it ends take another dump using the same command line as we used above.
    This dump will be used to show us what objects were added to the heap during the operation we are checking.
  • Run the Collect code (either by pressing the button you have prepared in the WinForms application or access the Collect.aspx page if this is a web application) and take another memory dump.
    This dump will be used to show us what objects are left on the heap after the operation has ended and after we called GC.Collect a few times to make sure all garbage was collected. All objects that cannot be accounted for (explained why they are still alive) are leaks and should be handled.

How to analyze the data

We first need to get some statistics on each one of the dumps to get a hold of the number of objects and their types that we currently have in the heap. To do that, we need to run the command: !dumpheap -stat on each one of the dumps and get a statistical view of all types of objects and the number of living instances.

We then need to compare between the 2nd and 3rd dumps to see if some of the objects did not decrease in number. If they haven’t (and we know they should have) these are our leaking objects.

We can find who is referencing them by using the !dumpheap -type [Object Type] (where [Object Type] is the namesapce and class name of the objects we want to check).

Then, we need to take one of the addresses (take the upper ones, they are the oldest ones) and run !gcroot [Object Address] on them to see who is referencing them.

Continue until you can account for all the objects in the 3rd dump and check if they are really supposed to be there after we called GC.Collect & GC.WaitForPendingFinalizers 3 times. Objects that should not be there should be traced to find who is referencing them and find out why they are being referenced.

That’s it. Quite simple, saves money but doesn’t produce nice graphs like the other tools 🙂

Not all memory leaks in .NET applications specifically relate to objects that are rooted or being referenced by rooted objects. There are other things that might produce the same behavior (memory increase) and we are going to talk about one of them.

What is the Finalizer Thread?
The finalizer thread is a specialized thread that the Common Language Runtime (CLR) creates in every process that is running .NET code. It is responsible to run the Finalize method (for the sake of simplicity, at this point, think of the finalize method as some kind of a destructor) for objects that implement it.

Who needs finalization?
Objects that needs finalization are usually objects that access unmanaged resources such as files, unmanaged memory and so on. Finalization is used to make sure these resources are closed or discarded to avoid actual memory leaks.

How does finalization works?
(NOTE: please email me if I’ve got something wrong or in accurate at this stage 😉 )

Objects that implement the finalize method, upon their creation, are being placed in a finalization queue. When no one references these objects (determined when the GC runs) they are moved to a special queue called FReachable queue (which means Finalization Reachable queue) which the finalizer thread iterates on and calls the finalize method of each of the objects there.
After the finalize method of an object is called it is read to be collected by the GC.

So how can the finalizer thread get blocked?
Finalizer thread block occurs when the finalizer thread calls to a finalize method of a certain object.
The implementation of that finalize method is dependat on a resource (its a general term for the sake of the general definition) that is blocked.
If that resource will not be freed and available for our finalize method, the finalizer thread will be blocked and none of the objects that are in the FReachable queue will get GCed.

For example:

  1. The implementation of the Finalize method contains code that requires a certain lock of a synchronization object (Critical Section, Mutex, Semaphore, etc) and that synchronization object is already blocked and is not getting freed (see previous post on Identifying Deadlocks in Managed Code for help on resolving this issue).
  2. The object that is being finalized is an Single Threaded Apratment (STA) COM object. Since STA COM objects have thread affinity, in order to call the destructor of that COM object we have to switch to the STA thread that created that object. If, for some reason, that thread is blocked, the finalizer thread will also get blocked due to that.

Symptoms of a blocked Finalizer thread

  • Memory is increasing
  • Possbile deadlock in the system (depends on a lot of factors, but it can happen)

How can we tell our Finalizer thread is blocked?

The technique for finding if the finalizer thread is blocked is quite easy and involves a few easy steps.

First of all, we need to take a series of dumps at fixed intervals (i.e. 5min apart). When we have the dumps we need to run the following set of commands from the SOS extension on all dumps and compare results (to find out how to load the SOS extension and set the symbols path look at this previous post):

  1. !FinalizeQueue – This dumps the finalization queue (not the FReachable queue). If you’ll see that the total number of object is increasing from dump to dump, we can start to suspect that our finalizer thread is blocked.
    NOTE: I say “suspect” because its still not certain at this point that the finalizer thread is blocked. This situation can also mean that the finalization of some of the objects takes a long time and the rate of objects being allocated vs. the rate of objects being finalized is in favor of the allocated objects, meaning, we are allocating objects that needs finalization faster than we are collecting them.
  2. !threads – This command will show us all .NET threads in the current process. The finalizer thread is marked at the end of the line by the text (finalizer) (surprisingly enough 😉 ). At the beginging of the line that has the (finalizer) text at the end of it you will see the thread’s index. We will need it to run the next command.
  3. ~[Finalizer Thread Index]k (i.e. ~24k)- This will dump the native call stack of the finalizer thread. If you will see in all dumps that the last function in the call stack (the top most) is something like ZwWaitForSingleObject or ZwWaitForMultipleObjects it means something is blocking our thread, usually a sync object.
    NOTE: If the call stack contains a call to a function named GetToSTA it means that the call to ZwWaitForSingleObject is there because we are tring to switch to the STA thread that created the STA objects and we are waiting to switch to it. This means that the STA thread is blocked for some reason.
  4. ~[Finalizer Thread Index]e!clrstack (i.e. ~24e!clrstack) – Dump the .NET call stack just to verify that if we don’t see a call to ZwWaitForSingleObject or ZwWaitForMultipleObjects we might be blocked due to a call to the .NET Monitor class (a native .NET implementation for a Critical Section). If we do see a call to Monitor.Enter it means we have some kind of a managed deadlock.

How to resolve a blocked finalizer thread?

If we are talking about a block that is being created due to a synchronization object (usually a critical section) we need to address it as a deadlock.

Managed Deadlock
To resolve a mangaed deadlock refer to the previous post on Identifying
Deadlock in Managed Code.

Unmanaged Deadlock
I’ll give a crash course to find unmanaged deadlocks, specifically Critical Sections since this is mainly a .NET debugging blog.

There is a Microsoft extension called sieextpub.dll (you can download it from here that is mainly focused at resolving COM issues. It has some useful commands for synchronization objects as well that we will use.

  • run the !critlist command. It will list all locked critical sections and the thread that is owning them (This is similar to running !locks but runs a lot faster).
  • Run ~[Thread ID]k (i.e. ~[22]k) to get the call stack of the owning thread.
  • If the problem is not with a critical section, but with another synchornization object such as a Mutex or a Semaphore, you can run !waitlist to see all the handles that every thread is blocking on. These handles should appear as parameters to functions such as WaitForSingleObject and WaitForMultipleObjects. We can use some native WinDbg commands to find these handles from the calls stack of the finalizer thread. For example:WaitForSingleObject:
    The handle itself will be shown in the call stack (using the kb or kv command, not just k) here:
    09b2f608 77ab4494 00000594 ffffffff 00000100 KERNEL32!WaitForSingleObject+0xf

    Compare this number to the number shown in the output of !waitlist and you will see who is the thread that is blocking the handle.

    WaitForMultipleObjects:
    Here the handle doesn’t appear directly in the kb command output since the function receives an array of handles. To find it we will need to find to parameters:
    00f4ff34 791d25d5 00000003 00f4ff58 00000000 KERNEL32!WaitForMultipleObjects+0x17

    The first bold one is the count of element in the passed array. The second one is the pointer to the array. To dump the array on the screen we will need to run the following command:
    dc 00f4ff58 – This will output the memory at that address and the output will look something like this:00f4ff58 00000700 00000708 000006d4 81b35acc ………….Z..
    00f4ff68 03a50008 b6788cb0 00000000 00000003 ……x………
    00f4ff78 00000000 ffffffff 00000000 00f4ff4c …………L…
    00f4ff88 8042f639 00f4ffdc 7920fd39 791d25e0 9.B…..9. y.%.y
    00f4ff98 ffffffff 00f4ffb4 791d254c 00000000 ……..L%.y….
    00f4ffa8 00dfcdf4 00000000 791d4d50 00f4ffec ……..PM.y….
    00f4ffb8 7c57b388 03a50008 00dfcdf4 00000000 ..W…………
    00f4ffc8 03a50008 7ff9f000 00dfc8ac 00f4ffc0 …………….

    We need to relate to the bolded number since we earlier saw that we have 3 handles to watch for. We should look to see if they appear in the output of the !waitlist to see who is blocking on them.

STA COM issues

STA COM issues are usualy caused due to the thread in which the STA object was created is blocked. To quickly find to which thread the finalizer thread is trying to switch to in order to call the destructor of the STA COM object we will use the sieextpub.dll that we mentioned above and call the !comcalls command which will simply show us the two important figures, the index of the thread that is trying to switch and the index of thread that we are trying to switch to.

Best resolution way – Avoidance

The best way of resolving blocked finalizer thread is avoiding it.
The first rule of thumb is AVOID FINALIZATION. If you don’t have to use it DON’T.

The only case implementing the finalize method is important is in a case where your class holds some private members that are native resources or that call native resources (SqlConnection for example, various Streams like FileStream and so on) in which case it is best to use the IDisposable pattern. You can find a lot of information on the internet about that but I’ll just point out a few interesting links such as this (from Eric Gunnerson’s blog. He is the Visual C# PM), and this excellent post (from Peter Provost’s blog).

In regards to STA COM object, the minute you don’t need them call Marshal.ReleaseComObject. This function wil guarentee that the COM object will get released the minute you call this function and NOT when the next GC will occur.

This was a long post, but I think it worthwhile. It a very important not to block the finalizer thread. I know that having only one without some watchdogging mechanisms is not a good design and Microsoft are aware of that.

Some additional resources for extra reading:

http://blogs.msdn.com/maoni/archive/2004/11/4.aspx – An excellent post by Maoni.

http://msdn.microsoft.com/msdnmag/issues/1100/GCI/ – An excellent article on Garbage Collection in .NET. Specifically read the “Forcing an Object to Clean Up” section which talks about the finalization of objects and a few other things.

http://www.devsource.com/article2/0,1759,1785503,00.asp – An excellent article on DevSource about .NET memory management and Finalization