Okay I’ve been tracking down a mysterious explosion in “Allocated Bytes/sec” performance counter for the entire day. I’ve been watching an application that’s been running happily in a live environment for several days now for the first time and I’ve been keeping an eye on the performance counters every now and then.
Well today I noticed something very unusual. The Allocated Bytes/sec was fluctuating between 250,000 and 600,000 bytes per second and Gen 0 collections were happening at a staggering 1.5 collections per second! Something was giving the garbage collector a workout. While the overall stability of the application was unaffected (because the Garbage Collector was doing its job after all) I found it unsettling and I needed to find out what was causing the allocations.
It took a few hours to realize that I had left another machine open to a web page which is using AJAX to constantly refresh statistical data from a remoting server (the one I’m trying to debug) but once I found that out, I was still perplexed as to why this statistical refresh could be causing so many allocations and GC’s. All I was doing is this:
LoggingStatistics stats = new LoggingStatistics( ); stats.QueuedTotal = Convert.ToInt32( _CounterQueueTotal.NextValue( ) ); stats.QueuedPerSecond = _CounterQueueRate.NextValue( ); stats.WritesTotal = Convert.ToInt32( _CounterWritesTotal.NextValue( ) ); stats.WritesPerSecond = Convert.ToInt32( _CounterWritesRate.NextValue( ) ); stats.CurrentQueueSize = Convert.ToInt32( _CounterQueueSize.NextValue( ) ); return stats;
As you can see, I am requesting the NextValue of 5 performance counters. The performance counters are instances within a Singleton object configured to live forever so the actual PerformanceCounter components themselves are not being re-initialized on every call. But as it turns out, calling NextValue is extremely resource hungry. Now I’ve never worked with performance counters prior to .NET so I’m not sure what is all involved in the interop, but half a meg of allocations and 1.5 garbage collections per second (the above method is called once per second, and the collections are happening more frequently) seems way too high for me.
So now I have to find an alternate solution. Because if I have two or more clients connected to the AJAX web page, those statistics will be multiplied. Quite simply, I can’t rely on performance counters for this.
Fortunately, the application acting as the remoting server delivering the performance counters is also the one managing their values. For the purpose of seamless integration with Windows Server, I am still going to have to update the performance counters but at least then I can manage the frequency. What I pain.
By the way I ran into this web page after I discovered the problem which confirms my findings: