title: Should Application_End fire on an automatic App Pool Recycle?
body: <p>I have read <a href="https://stackoverflow.com/questions/5320180/asp-net-mvc-why-does-my-app-keep-restarting">this</a>, <a href="https://stackoverflow.com/questions/844050/rule-of-thumb-for-amount-of-usage-memory-it-takes-to-make-a-worker-process-recyc">this</a>, <a href="https://stackoverflow.com/questions/10830633/determine-memory-used-by-asp-net-cache-in-shared-hosting">this</a> and <a href="http://blogs.msdn.com/tess/archive/2006/09/06/net-memory-usage-a-restaurant-analogy.aspx" rel="nofollow noreferrer">this</a> plus a dozen other posts/blogs.</p>
  
  <p>I have an ASP.Net app in shared hosting that is frequently recycling. We use NLog and have the following code in global.asax </p>
  
  <pre><code>void Application_Start(object sender, EventArgs e) 
  {
      NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
      logger.Debug("\r\n\r\nAPPLICATION STARTING\r\n\r\n");
  }
  protected void Application_OnEnd(Object sender, EventArgs e)
  {
      NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
      logger.Debug("\r\n\r\nAPPLICATION_OnEnd\r\n\r\n");
  }
  
  void Application_End(object sender, EventArgs e) 
  {
          HttpRuntime runtime = (HttpRuntime)typeof(System.Web.HttpRuntime).InvokeMember("_theRuntime", BindingFlags.NonPublic  | BindingFlags.Static  | BindingFlags.GetField,  null,  null,  null);
  
  if (runtime == null)
      return;
  
  string shutDownMessage = (string)runtime.GetType().InvokeMember("_shutDownMessage",  BindingFlags.NonPublic  | BindingFlags.Instance  | BindingFlags.GetField,  null,  runtime,  null);
  
  string shutDownStack = (string)runtime.GetType().InvokeMember("_shutDownStack",   BindingFlags.NonPublic  | BindingFlags.Instance  | BindingFlags.GetField,  null,  runtime,  null);
  
  ApplicationShutdownReason shutdownReason = System.Web.Hosting.HostingEnvironment.ShutdownReason;
  
  NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
  logger.Debug(String.Format("\r\n\r\nAPPLICATION END\r\n\r\n_shutDownReason = {2}\r\n\r\n _shutDownMessage = {0}\r\n\r\n_shutDownStack = {1}\r\n\r\n",
                  shutDownMessage, shutDownStack, shutdownReason));
  }
  
  void Application_Error(object sender, EventArgs e) 
  {
      NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
      logger.Debug("\r\n\r\nApplication_Error\r\n\r\n");
  
  }
  </code></pre>
  
  <p>Our log file is littered with "APPLICATION STARTING" entries, but neither <code>Application_OnEnd</code>, <code>Application_End</code>, nor <code>Application_Error</code> are ever fired during these spontaneous restarts.  I know they are working because there are entries for touching the web.config or /bin files.  We also ran a memory overload test and can trigger an <code>OutOfMemoryException</code> which is caught in <code>Application_Error</code>.</p>
  
  <p>We are trying to determine whether the virtual memory limit is causing the recycling.  We have added <code>GC.GetTotalMemory(false)</code> throughout the code, but this is for <strong>all of .Net</strong>, not just our App´s pool, correct?  We've also tried</p>
  
  <pre><code>var oPerfCounter = new PerformanceCounter();
  oPerfCounter.CategoryName = "Process";
  oPerfCounter.CounterName = "Virtual Bytes";
  oPerfCounter.InstanceName = "iisExpress";
  logger.Debug("Virtual Bytes: " + oPerfCounter.RawValue + " bytes");
  </code></pre>
  
  <p>but don't have permission in shared hosting.</p>
  
  <p>I've monitored the app on a dev server with the same requests that caused the recycles in production with ANTS Memory Profiler attached and can't seem to find a culprit.  We have also run it with a debugger attached in dev to check for uncaught exceptions in spawned threads that might cause the app to abort.</p>
  
  <p>My questions are these:</p>
  
  <ul>
  <li>How can I effectively monitor memory usage in shared hosting to tell how much my application is consuming prior to an application recycle?</li>
  <li>Why are the Application_[End/OnEnd/Error] handlers in global.asax not being called?</li>
  <li>How else can I determine what is causing these recycles?</li>
  </ul>
  
  <p>Thanks.</p>
  
  <p>EDIT: Based on answer by @Jani Hyytiäinen</p>
  
  <p>Scenario:
  Thread #1 begins and is followed by thread #2.  Thread #1 hits memory limit but continues processing.  Thread #3 begins.  Thread #1 finishes, but #2 processes more than 60 seconds after #1 has hit the memory limit.  </p>
  
  <p>The pool then ungracefully aborts?  What http responses will #2 &amp; #3 receive (These are AJAX calls, but I am getting 504 errors in Fiddler)?<br>
  Is the request for #3 accepted or does it just queue until a new pool has started up?<br>
  Is there any way to know that the memory limit has been hit or is about to be?</p>
  
  <p>Any strategies welcome.</p>