5

So we're stress testing an ASP.NET application developed by an external company. We're doing roughly 50 requests per second, and after about half an hour each of the 48 worker process (w3wp.exe) is up to about 400 MB and counting. Running on IIS7.

Now after meddling with dotTrace, I'm fairly certain there is a memory leak here, but it's hard to be 100% certain without knowing the application. When we confronted the developers with this theory they dismissed it after 30 seconds saying something like "memory is handled automatically in .NET". Surely .NET would have garbage collected 48x~400MB if it was finalized data?

Anyway, I'm used to working with WinForms. How exactly do one create memory leaks in ASP.NET? Is the ONLY way by (mis)using the Application and Session objects in .NET?

edit

I have since posting this question learned that holding static references to objects in the request handlers (be it a web service class, web form or whatever) will cause "leaks". Probably not the correct term here, but anyway... This I was unsure of, because I thought the handler classes were killed and recreated after each request by IIS.

So code like this:

public class SomeService : IService
{
    public static List<RequestData> _requestDataHistory = new List<RequestData>();
    public void SomeRequest(RequestData data)
    { 
        _requestDataHistory.Add(data);
    }        
}

WILL crash your server sooner or later. Maybe this was obvious to most people, but not to me :-)

Still unsure whether or not this would be a problem if you removed the static keyword though. Are instances disposed after each request?

Nilzor
  • 185
  • 2
  • 9

2 Answers2

2

The developers might be right. In the .Net world, garbage collection and freeing memory happens when needed. I.e. if, there's plenty of memory available to the application, it may consume more and more, until the operating system does not allow more allocation. You shouldn't worry about that, unless it really causes problems.

Of course, there may be memory leaks, if the application does not properly dispose unmanaged resources, like sockets, file handlers, etc. Look at the operating system objects (in task manager, you can enable handles and user objects columns) to see how they grow.

As you stated, Application or Session object misusing can also be a cause.

I'm wondering why you would have 48 application pools (worker processes). This is overkill, and you do not need that at all.

The GC manages memory per process, and 400MB per process is not that much at all. Reduce the number of app pools to the nr. of cores - 1, and then stress test the application. If then it grows too much, you may be concerned about memory leaks.

Based on your additional information, yes, in that case the history list will grow indefinitely. Static objects are created once per application domain, and live until the appdomain lives.

I do not advise you to arbitrary remove the static keyword, unless you know that you do not break some application logic. Investigate why that data is collected anyway, and what it is used for. The code has another problem as well - it's not thread safe, it's behavior is undefined when 2 requests came in at the same time, and decide to add data to that list.

Better move your question to stackoverflow.com, as it's a programming question, and not administrative one.

If you are not in control off that code, and really want to just solve your memory problem, you can set your apppools to recycle after X number of requests, or after they get more than Y amount of memory - but again, that's not a real solution.

Sunny
  • 5,722
  • 3
  • 21
  • 24
  • It causes problems. The worker processes eventually crash because they're of out of memory when trying to allocate more. I agree that 400MB alone is not much, but 400*48 MB is. If we cut down to one worker process, it will use the same amount of memory as the 48 combined eventually (although not tested, not in my power to do so) – Nilzor Aug 22 '11 at 08:59
  • pls, check my edit – Sunny Aug 22 '11 at 12:46
  • Thanks for your input. I guess the problem has turned into a programming question, yes. I'm not in control of the code. As a workaround while we're waiting for a fix, we'll use the recycling technique - thanks! – Nilzor Aug 23 '11 at 08:39
0

Memory Leaks, in the general sense, is the negative/unanticipated results of coding logic which is not releasing its unused (or no longer used) resources correctly (or at all) while still reserving additional resources for new/continuing use/processing requirements. The overall resource "footprint" then continues to grow, even through the actual requirements may not necessarily be increasing if the proper "clean-up" of correctly utilizing and releasing resources is in place.

In short, it is not limited to logical programming "abuse" where it can be from incorrect assumptions of resource management or just the lack of it.

user48838
  • 7,393
  • 2
  • 17
  • 14