I Should Know This
There's a lot of things I've taken the time to learn formally (ie. go to school, take a cert) which escape me when they would actually come in handy. In fact it becomes even more frustrating when we end up figuring out what happened...and it's something I already (should) know.
This once again became wildly apparent this week while I was troubleshooting some random web app. As it turns out, poor memory is the gift that keeps on giving, and my own memory is definitely feeling the festive nature of the holidays. In a very small nutshell, I forgot the following.
Every application you set up in a web site (including the root application) ends up being in its own application domain. It'll have its own set of assemblies, get JIT'd independently, and of course be completely isolated from the the contents of other application domains (Session, Statics, Cache, etc... won't be shared.).
Process: Contains the code and data of a program. Also contains at least one thread. Represents a boundary that stops it from wreaking havoc on other processes and requires special techniques to communicate across. Runs in a security context which dictates what it can and can't do. If it's running some .NET code then it contains one or more application domains.
An example of a process might be notepad.exe, or if we're talking about IIS aspnet_wp.exe (Win XP, Win 2000) or w3wp.exe (Windows 2003).
Application Domain: Are more efficient than processes. One process can load the .NET framework once and host many application domains. Each app domain might load its own assemblies (or even it's own child application domains), but will not have to reload the overhead of the .NET framework. Since each application domain runs within the .NET framework, it benefits from the features there of (things like Code Access Security, Managed Memory, JIT Compiling, etc...).
Application Domains also represent a boundary that you'll need special techniques to communicate across. Since more than one can be hosted in an process, it's common for the .NET Framework to load up and unload application domains at runtime. This is what happens when you recycle an IIS Application Pool, the application domains within it are unloaded and new app domains are created to service new requests.
In ASP.NET an Application Domain is created for every virtual directory that you configure and as application in IIS. Each can have it's own bin folder, web.config and IIS Application Pool.
It's worth mentioning that even though there's Application Domain boundary separation between applications, they can still inherit web.config settings from each other (if one is in a parent folder).
Application Pools (IIS 6 and above): Host one or more applications (Application Domains if we're talking about .NET code). If an application pool is running in worker process isolation mode, it can also spread those applications over one or more processes (a web garden)! They allow you a great deal of flexibility when it comes to deciding how much isolation you want to give your applications. You can use application pools to provide process level isolation for each application (each application can have its own w3wp.exe [or more if you web garden]). Application Pools can also combine multiple applications in a single application pool (saves resources).
And We're Back
Every now and then I get a little scared of the complexity that will be in development environments 20 years from now. Yes, the stuff being written will be extremely cool, and the tools that get used will no doubt be just as impressive. That being said, there will be a a lot of complexity in play in the future and a tonne to be aware of.
With .NET v4.0 in the works, a lot of focus seems to be on parallel computing (ie. PLINQ) I can't imagine the computing world is about to get much simpler.
Keep your seat belt on.