15

I had some code in an ASP.NET application running on Server 2008 R2 + IIS 7.5. Whenever I loaded a particular page, it would hang forever and send IIS to 100% CPU usage. I eventually tracked down the problem.

public string Comments
{
    get { return this.Comments; }
}

Oops - should have been return this.Photo.Comments. So, my question is, why didn't .NET generate a StackOverflowException, but instead let IIS run at 100% CPU for far longer than it should have taken. In my experience programming with .NET, it takes seconds or less to get a StackOverflowException when doing something like the above. So how could it still be running for almost 30 minutes on IIS?

2
  • Did the worker process maybe die and retried the operation? I accidentally coded a SO the other day, and it killed ASP.NET (Sharepoint in my case) pretty quickly. Commented May 10, 2011 at 9:04
  • 1
    Since .net 4 optimizes tail recursion, this might have been rewritten to a loop. You can verify this by looking at the IL. Commented May 10, 2011 at 13:44

3 Answers 3

5

It's possible the JIT compiler optimised out a method call to YourClass::get_Comments() (which is what the IL would look like) and inlined the code with a jmp (or whatever the x86 assembler would be) loop construct because there weren't any values being passed around. Just a thought.

This old article is worth a look:

Jit Optimizations: Inlining (II)

"A typical example of a really good candidate for inlining is a property getter/setter. These are usually really small methods that usually just do a memory fetch or store, so it's usually a size and speed win to inline them."

As is:

Writing High-Performance Managed Applications : A Primer - Managed Code and the CLR JIT

I also reproduced this with a simple console application:

class Program
{
  static void Main(string[] args)
  {
    MyClass mc = new MyClass();
    string s = mc.Comments;
  }
}

public class MyClass
{
  public string  Comments
  {
    get { return this.Comments; }
  }
}

In debug mode with optimisations turned off I get a stack overflow exception thrown. Upon turning on Jit Optimisations and compiling a release build the app just runs forever. This suggests that inlining to a loop has probably happened.

This also appears to be the case with C#2.0, 3.0 and 4.0.

Sign up to request clarification or add additional context in comments.

1 Comment

This makes sense, thanks. I tried debug mode and interestingly it just crashed IIS and gave me a 503. Anyways, problem solved.
1

I tried putting this code into a class library and running it with a unit test.

It crashes the MS test agent with a stack overflow exception.

What may be happening is that you are getting a stackoverflow exception. This is crashing the application pool. IIS then pulls up a new copy of the app pool, and it gets crashed again ....

Check your event logging for application pool recycling / stops.

Comments

0

Does this happen in development as well as release?

I'm sorry I don't know for sure, but here is my speculation. Somewhere you have an Auto-retry configured. So the operation process fails from a StackOverflowException. Rather than the user getting a message, IIS retries with a new process. This goes on and on and on. And so the repeated retries eat all the CPU.

I've searched to try and find an auto-retry mechanism that might account for it, but had no luck so far, but you will know more about your configuration.

Another check you could try is write something which allocates a huge amount of memory and see if the same thing happens with OutOfMemoryException. If it does, it is almost certainly an auto-retry.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.