HOWTO: Provision ASP.Net AppDomains and IIS6 Application Pools

This is a frequent source of confusion - how ASP.Net and IIS does application isolation. The key point to remember is that IIS runs native code and thus relies on NT user identity (and thus NT process) for isolation, while ASP.Net runs managed code with CAS and thus can run its own isolation mechanism within a NT process.

Question:

I read somewhere that running applications in different pools takes up more memory. My understanding of asp.net is that all applications run in their own space under the shared memory space inside w3wp.exe. process.
1. So how is that different from creating seperate pools?
3. Is there a free software to simulate about a 100 connections to a site?
2. Lets say i do run applications in different pools and limit the mem to 10 MB per site, and set it to recycle once limit is reached. Will that be better?

I have a webhosting server with 50 sites and 1 GB ram. (so 50 X 10 = 500 MB) approx

Some of then do take up quite a bit of mem so i can set those up with more space.

Can someone provide me with link or some info on this?

Thank you

Answer:

I do not understand what you mean by "all applications run in their own space under the shared memory space inside w3wp.exe process" because I think that is where your understanding goes awry. Here is how I view ASP.Net applications and IIS:

  • The basic unit of isolation for an ASP.Net application is its AppDomain. There is exactly one ASP.Net application per AppDomain
  • Every AppDomain identifies and "owns" some portion of the URL namespace. i.e. /ASPX1/WebApp.aspx
  • IIS6 running in Worker Process Isolation Mode partitions the entire URL namespace of the server to be serviced by arbitrary number of Application Pools (minimum of one Application Pool)
  • Application Pool configuration controls the number of NT processes that service the Application Pool (minimum of one w3wp.exe)

Since configuration of Application Pool is arbitrary, it means that it is possible to:

  • Run multiple AppDomains inside of one NT process

    i.e. "/" is serviced by DefaultAppPool, /ASPX1/WebApp.aspx and /ASPX2/WebApp2.aspx are ASP.Net Applications in their own AppDomain, and both AppDomains are sharing the same AppPool and hence same process

  • Run one AppDomain per NT process

    i.e. /ASPX1 is serviced by AppPool1 and /ASPX2 is serviced by AppPool2, /ASPX1/WebApp.aspx and /ASPX2/WebApp2.aspx are ASP.Net Applications in their own AppDomain, so each WebApp is in their own Application Pool and hence their own process

  • It is not possible to run one AppDomain over multiple NT process

In general, it is a poor idea to isolation ASP.Net applications by using Application Pools. Why?

  1. ASP.Net applications all require the .Net Framework, which is a fixed overhead (in the neighborhood of at least 20MB RAM) paid by every process that loads an ASP.Net application. Suppose you have 10 ASP.Net applications. If each application is in its own Application Pool, you can have up to 10 copies of the .Net Framework loaded in memory by each w3wp.exe of each Application Pool. Efficiency says that you really only need one copy of the .Net Framework for all of the ASP.Net applications, and this is possible only if all 10 ASP.Net applications are in the same Application Pool.
  2. ASP.Net applications do not benefit from Application Pool based isolation (by process identity) because ASP.Net runs managed code, which already has CAS and does NOT rely on user identity nor process space for isolation. AppDomain is the logical concept that is enforced by ASP.Net to isolate the ASP.Net applications. Of course, this is a different story for native code applications like ASP, ISAPI, CGI which do benefit from using process space for isolation.

Thus, if you isolation ASP.Net applications using Application Pools, not only are you wasting system RAM resources loading duplicate .Net Framework libraries into memory, you are also gaining no isolation benefits. It is a lose-lose configuration.

For a webhosting server, I recommend creating one Application Pool for use by all ASP.Net applications, and you configure this Application Pool to turn off all health monitoring checks except for private memory limit at 60% physical memory. In particular, you want to turn off periodic recycling and idle timeout, both default values that wreck havoc with ASP.Net because they periodically recycle the worker process and thus causes the subsequent request to re-load the .Net Framework into memory, which takes non-trivial amount of time.

For ASP/CGI/ISAPI based applications, you should still isolate them by Application Pool and use the default IIS6 settings as base guideline, plus any others that you want

As for how to distribute Websites amongst Application Pools, I would first determine the necessary isolation between the websites (ASP.Net applications should share the same application pool while native code applications of different websites should be separated into different application pools), then calculate the memory footprint of each w3wp.exe of each possible Application Pool, and make sure the system can handle that (and have like 256MB remaining buffer for the host OS's use).

In other words, just blindly isolating websites by creating Application Pools that have unique Application Pool Identites will quickly get you into trouble. Efficient provisioning requires that you analyze what sorts of applications you are running, how the applications need to be isolated by each other, and the representative memory footprint of each application - so that you can make sure it fits within the server's hardware limits or whatever availability guarantees you are making.

//David