Monday 30 June 2008

A setting that can boost performance of any heavily network-dependent application

By default .NET allows only 2 connections to a given network address per AppDomain. In most cases this works fine but if your app makes a couple of dozens network calls a second then this value might be too small and it might actually cause a bottleneck that is very hard to diagnose. I decided to increase the value of this setting to the value that is recommend by Microsoft (number_of_cores x 12) and one of my services speeded up significantly. Having said that I have to stress that there is no guarantee this setting will work in your case. Remember, measure, measure and once again measure when you optimize.
And the setting is:
<add address="*" maxconnection="96"/>

WCF service hangs - the pool of available sessions might have been exhausted

By default WCF accepts only 10 concurrent sessions which is not enough for most applications. If there are 20 clients then 10 of them will be blocked until their requests time out. You can always increase the number of sessions

but this is going to work as long as you control all the clients. If you don't then some of them might not properly close their sessions which next might lead to a resource leak on the service side. This is not an easy problem to solve unless you are ready and able to abandon sessions.
From my perspective it's much more important to know that a service is about to reach it's limit of sessions or it is hung because it already has reached it. Unfortunately as far as I know there is no out of the box way of monitoring the number of active sessions per WCF service using Performance Counters. This leaves us with only one option, namely we have to write a custom performance counter on our own. This can be done as a WCF extension that implements IChannelInitializer and  IInputSessionShutdown interfaces.
When a service seems to be frozen the story is not that simple as there might be dozens of reasons why it is in such a state. The only way I know to prove or disprove that the problem is related to the fact that there are no available sessions is to create a memory snapshot of the process where the service is hosted in and use Debugging Tools for Windows to check the state of all ServiceThrottle objects.
The following steps shows how to carry out such an investigation :) :
0. Install Debugging Tools for Windows and copy C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll (extension for .NET debugging) to the folder where Debugging Tools for Windows are installed.
1. Find the id of the process that is hosting the WCF service we are examining. In my case it is one of the IIS worker processes.

2. Create a memory snapshot using the adplus script which is part of Debugging Tools for Windows. By default adplus creates all snapshots under the folder where the Debugging Tools for Windows is installed.

3. Launch windbg.exe (the same location as adplus) and open the memory snapshot.

4. Type .load sos and press enter to load sos.dll into windbg.

5. Type !dumptheap -type ServiceThrottle -short in the command line to list all objects of type ServiceThrottle that exist on the managed heap. By the list of all objects I mean a list of their addresses in memory.

6. For each address on the output list carry out steps 7 - 8
7. Type !do address of the object to see what's inside of it.

8. The ServiceThrottle object has bunch of fields but only one of them which is called sessions is interesting from our perspective. Type !do address of the sessions field to see what's inside of it.

If you find a sessions field that has count and capacity fields set to the same value then you know that the pool of available sessions has been exhausted. If you can't find it then at least you know that there is something else wrong with your service.
Happy debugging :)

Saturday 7 June 2008

Windows XP 64 bit - a relatively unknown but great operating system

A few weeks ago I got a new beefy machine and the guy who was setting it up asked me if I wanted to try XP 64 bit. At the beginning I didn't see any compelling reason to move to a new platform but then I realized that XP 32 bit is not going to take full advantage of 4GB of RAM and I decided to give it a try. I'm glad that I've made that decision as it turned out that XP 64 bit is superior to XP 32 bit as a foundation for software development.
  • XP 64 bit can leverage all 4GB of RAM which allows me to run 4/5 instances of VS.NET, SQL Server, Outlook, Firefox and a dozen of background applications without any noticeable performance degradation.
  • XP 64 bit shares core components with Windows Server 2003 which would explain its great performance and reliability.
  • XP 64 bit comes with IIS 6.0. I suppose I don't have to explain why this is big. If my point is not clear to you, just compare IIS 5.1 and IIS 6.0 and you will immediately understand what I'm talking about.
I asked quite a few software developers about XP 64 bit and none of them has ever considered installing it. It looks like the Marketing Department at Microsoft is very busy coming up with even longer names of Microsoft products :) and they have no time to market one of the best systems they've released.