Yesterday morning, I was brought in to a high profile project to diagnose a high memory condition within an IIS worker process running .NET 3.5 code. Logged in to the server and quickly realized something serious was going on. The W3WP process was currently allocating in excess of 2.3 GB of memory which is a new record in my book:
The application is running under IIS 7 and Windows 2008 which means I could take a memory snapshot using Task Manager. Once the dump was complete, I fired up WINDBG and started the analysis. On first glance, I noticed there were in excess of 60K System.Data.DataTable objects consuming over 30MB. There were also 215K DataColumn and 2.7 million DataRow objects on the heap consuming an additional 300M of memory. Using GCRoot on one of the DataTable objects revealed they were being created by System.Web.Util.Profiler which is an internal class, strange. After rooting down even further in to the DataTable, I was able to determine the table name was “Trace_Querystring_Collection”. Certainly this could not have been created from the application and must be related to the tracing classes. Sure enough, development had the following configuration in their web.config:
<trace enabled="true" traceMode="SortByTime" requestLimit="5000" localOnly="false" />
The default on the requestLimit is 10. Each time a request comes in, a new DataTable is created which contains everything about the request. When the requestLimit is set high, it keeps these objects in memory therefore boosting the W3WP process space. As a result, this was negatively affecting performance tests and causing panic within development. Disabling the trace option completely cleared the issue.
No comments:
Post a Comment