If broken it is, fix it you should

Using the powers of the debugger to solve the problems of the world - and a bag of chips    by Tess Ferrandez, ASP.NET Escalation Engineer (Microsoft)

Questions on application domains, application pools and unhandled exceptions

Questions on application domains, application pools and unhandled exceptions

Rate This
  • Comments 33

I got an email with some questions around application domains, application pools and unhandled exceptions from a developer that was frequently seeing his website crash, and also had some related issues with session loss in his application.

I have written before about unhandled exceptions and session loss due to appdomain restarts but I thought his questions would serve as a nice refresher.

From what i read, my understanding is that a website has an app pool associated with it. This app pool leads to the creation of a w3wp.exe process. Inside this app pool/w3wp.exe process, an application domain is created.

Tess:  This is correct.  In IIS you can create different application pools that have different healthmonitoring settings, run under different user contexts etc. and when you create a web site you choose which application pool it will run under.  Each application pool will then spawn it's own w3wp.exe process (or multiple if you have web gardening turned on) when the first request comes in.

The process (w3wp.exe) contains multiple application domains, typically a shared domain, a default domain, a system domain and one application domain per web application (virtual directory marked as application). 

An application domain recycling is different than an application pool/proccess (w3wp.exe) recycling, right?

Tess: Yes.  An appdomain can recycle without recycling the process.  Simplified an appdomain is a process within the process with it's own statics (cache/session etc.), but all appdomains in the process share the same GC, threadpool, finalizer thread etc.

An appdomain recycle is triggered by a few things like web.config changes, directory name changes etc.  You can find most of the appdomain recycle reasons in this post.  When an appdomain recycles the process stays up, however when the process goes down the appdomains in the process will of course also go down.

Can unhandled exceptions cause the application domain to recycle ?

Tess:  It depends on what you mean by unhandled exceptions.  In ASP.NET there is the concept of unhandled exceptions that are caught by the global error handler or page error handler. i.e. the ones that give you the yellow exception output when you view a page.  They will be listing as unhandled exceptions in eventvwr, but in reality they are handled by the page error handler, and they will neither crash the appdomain or the application/w3wp.exe process.

If on the other hand you have an exception that occurrs on a non-request thread, such as a timer thread or the finalizer thread and you dont have a try/catch block around it, it is really an unhandled exception, and such unhandled exceptions will cause the process to go down and take all the appdomains with it.

What exactly happens inside the application domain when an unhandled exception occurs ?

Tess:  The process shuts down, and the appdomains are unloaded so anything inside it is gone including session vars etc.

Is there a setting in any of the config files that will prevent the application domain from recycling ?

Tess: There is a legacyUnhandledExceptionPolicy see this post for more info, that will cause a 2.0 process to behave as 1.1, i.e. not shut down the process and instead just quit processing the current thread of execution. I would seriously advice against using it though other than as a temporary measure while you troubleshoot the unhandled exception as it may cause your process to behave erratically, since you don't really know what has processed and what hasn't.  For example if an exception occurrs during finalization you will not know if you have released all the native handles you were supposed to or not.

Laters,

Tess 

  • That was very helpful .. Thanks

  • Thanks for clearing up some of those things.  One of the things I struggled with for a long time when I started reading your blogs and the blogs of your peers was trying to create a dump on an "unhandled exception".  I didn't understand that these exceptions were really handled by the  global application handler.

  • My latest in a series of the weekly, or more often, summary of interesting links I come across related to Visual Studio. The Web Developer Tools Team announced the release of the Dynamic Data Wizard Preview 0806 for VS 2008 SP1 . US ISV Developer Evangelism

  • Link Listing - August 21, 2008

  • A timely reminder! Thanks Tess.

  • Tess,

    Thanks for answering my questions. I wasn't expecting you to write a whloe blog post about it :)

    I was able to solve the problems following the steps in your <a href="http://blogs.msdn.com/tess/archive/2006/08/02/asp-net-case-study-lost-session-variables-and-appdomain-recycles.aspx">other blog post<a/>

    i was wondering if i could pick your brains a bit more :)

    I have a follow-up on Question 3, i.e. "Can unhandled exceptions cause the application domain to recycle ? "

    You say that in asp.net an unhandled exception on a  normal request thread will be caught by the global error handler or page level handler and will not cause the appdomain or the process to restart. But lets say hypothetically the developer hasn't written any global error handler (in global.asax) or page level handler. In this case will the appdomain or process or both crash or does asp.net have something built in that will always catch it?

    In Question 4, "Is there a setting in any of the config files that will prevent the application domain from recycling ?"  You mention a solution that will prevent  the process from crashing and  the worker thread will be lost. What about the application domain ? will it survive or will it crash ?

    Also, an additional question. Could you elaborate a bit on the topic of  request threads and non request threads inside an application domain ? Or if you could point me to any good articles on how things work inside an application domain.

    Thanks again. You're a life saver.

  • Hi Tarique,

    Even if the developer has not written a global or page level errorhandler they wouldnt crash the system.  Instead the user would see an exception or error page.

    About Question 4,  no, the application domain would still stay up.

    And finally on the request threads and other threads...  by request threads I mean threads handling requests, and non-request threads would be timer threads and the finalizer for example...

  • Hi Tess.

    I read this post and it hits the same spot has some others I read while trying to find a solution for a problem.

    Lost sessions are always related to session timeouts and appdomain/worker process recycling, but what about if only some sessions variables are randomly lost, way before their defined timeout, without the process recycle (no application_start called)? Some sessions just vanish! :s

    Maybe I should just submit my problem to MS support...

    Great blog in a gray area for must of us developers.

    Best regards

  • If you are just loosing a few session variables that would either mean that the code that was supposed to set them never ran, or they are overwritten.

    I would check for exceptions to see if any occurred preventing the variables to be set. or if you are populating them with content from shared/static variables that is maybe changed by other threads.

  • just one more note on that topic,  if you have a webfarm, make sure that you are either using sticky sessions so all requests go to the same server, or that you use out of proc session state like sql session state or a state server, otherwise the sessions would be available on one server but not the other...

  • Hi Tess,

    I have big object (wrapper around managed code) that I want to load somehow into IIS process but to not be subject of AppDomain recycling. Is it possible? If so how?

    This object will need to be accessed by current app pool that is processing the web requests, once app pool recycles memory is not freed up fast enough for the new app pool to have enough memory to allocate this object in the new pool. Yes, we have extreme memory fragmentation on the system that is the true source of the problem, we use ASP.NET 2.0. If we write something like ISAPI filter and have the object loaded there, and then marshaled-cross-domain boundary from regular apps, is that reasonable, will it even work? Any better ideas?

    Thanks,

    Alina

  • Hello Tess,

                    This question is about App domains and Sessions. Is it possible to have IIS run each User Session in a seperate App Domain. If Yes, Could you please let me settings in the config file that affect this.

    Regards,

    Anil.

  • Hi Anil,

    I am assuminig that you dont mean one appdomain per user, as this would mean that you would have a lot of appdomains:)  so I am not really sure that I am understanding your question...  

    If the question is about having each appdomain/website in a separate process, then you can do so by assigning them to different application pools.  

    If the question is about how you can save session state even over appdomain restarts, the answer is to use out of process session state, like asp.net state server or sql server session state.

  • Hello Tess,

                    Thanks for your reply. In fact I was asking if it is possible to have a seperate app domain per user. I agree with you this could result in a lot of app domains.

    Regards,

    Anil.

  • Hi Tess.

    Regarding your phrase: "but all appdomains in the process share the same GC, threadpool, finalizer thread etc", is that mean that GC don't know the boundaries of each appdomain memory limit?

    I suspect that’s the case and that’s why gc does not know he must collect NOW or the pool for that application will recycled.

    If I'm right – that’s a big bug in the GC, if I'm wrong – then I must have a big illusive bug in my system. U c, I found myself having to call gc.collect() on every page_unload event of my website(s) just to stop the memory to increase almost every refresh of almost every page. Only the "Induced DC" stop that.

    For few days now I'm trying to figure out if I have some unmanaged unreleased resources, either by going over my code path or using the debug tools u teach us here so well, but I can't seem to find any (I even panicked and did some "object=null " for managed objects like xmlDocument and such – even though I knew I don’t have to…).

    Love to hear your thoughts on the matter.

    Thanks a lot for all your great posts.

    Ilan.

Page 1 of 3 (33 items) 123
Leave a Comment
  • Please add 1 and 7 and type the answer here:
  • Post