Question

I have a Azure Cloud project with one Web Role. The Web Role endpoints return HTTP 400 - Bad Request almost immediately after the deployment. When I check in trace message logs, I see below exception -

Type : System.InvalidOperationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Custom counters file view is out of memory.
Source : System
Help link : 
Data : System.Collections.ListDictionaryInternal
TargetSite : Int32 CalculateMemory(Int32, Int32, Int32 ByRef)
HResult : -2146233079
Stack Trace :    at System.Diagnostics.SharedPerformanceCounter.CalculateMemory(Int32 oldOffset, Int32 totalSize, Int32& alignmentAdjustment)
   at System.Diagnostics.SharedPerformanceCounter.CreateCategory(CategoryEntry* lastCategoryPointer, Int32 instanceNameHashCode, String instanceName, PerformanceCounterInstanceLifetime lifetime)
   at System.Diagnostics.SharedPerformanceCounter.GetCounter(String counterName, String instanceName, Boolean enableReuse, PerformanceCounterInstanceLifetime lifetime)
   at System.Diagnostics.SharedPerformanceCounter..ctor(String catName, String counterName, String instanceName, PerformanceCounterInstanceLifetime lifetime)
   at System.Diagnostics.PerformanceCounter.InitializeImpl()
   at System.Diagnostics.PerformanceCounter..ctor(String categoryName, String counterName, String instanceName, Boolean readOnly)

It seems that the problem is caused when .NET hits the cap for the amount of memory it is allowed to allocate to performance counters.

So, I tried to increase the memory allocation with the below entry in my Web.config -

<configuration> 
<system.diagnostics> 
<performanceCounters filemappingsize="33554432" /> 
</system.diagnostics> 
</configuration> 

But even with this, I still end up with the problem. Can someone please provide me some pointers to fix the problem?

Thanks!

Was it helpful?

Solution 2

From this documentation.

... If you define the size in your application configuration file, that size is only used if your application is the first application that causes the performance counters to execute. Therefore the correct location to specify the filemappingsize value is the Machine.config file. ...

OTHER TIPS

Are you using your own performance counters? We had the same exception in one of our applications, which created performance counters, but didn't dispose them properly.

Be aware that calling PerformanceCounter.Dispose() is not enough - it just inherits from Component.Dispose() and adds no additional functionality.

So always call PerformanceCounter.RemoveInstance() when disposing an instance of a multi-instance PerformanceCounter, otherwise your PerformanceCounter instances will grow until the reserved memory (512 KB by default) is full.

A sample pattern looks so (this.performanceCounters is a dictionary with the used performance counters):

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
    if (disposing)
    {
        if (this.performanceCounters != null)
        {
            foreach (PerformanceCounter counter in this.performanceCounters.Values)
            {
                counter.RemoveInstance();
                counter.Dispose();
            }

            this.performanceCounters = null;
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top